如何在主线程执行期间更改控件属性?

时间:2017-11-08 12:46:30

标签: c# multithreading c#-4.0

我知道有几个与我的问题相关的问题,我已经研究了所有问题,但似乎我仍然无法得到它。 某事like thislike this

我有一种方法可以通过FTP下载一些文件(大约需要5秒钟)。当我单击按钮下载文件时,我还想更改一个控件属性,以便可以看到“加载”类型的东西。

为此我有一个CircleProgressBar,其中“animated”属性默认设置为false。当我调用上一个方法时,我想首先将该属性更改为true,并在下载完成后将其设置为false。

我尝试了很多解决方案,但徒劳无功:

void UpdateMessage(bool value)
    {
        Action action = () => DownloadLC_Normal_CircleProgressBar.animated = value;
        Invoke(action);
    }
    private void DownloadLC_Normal_Button_Click(object sender, EventArgs e)
    {
        // try 1
        //UpdateMessage(true);

        // try 2
        //DownloadLC_Normal_CircleProgressBar.Invoke((MethodInvoker)(() =>
        //{
        //    DownloadLC_Normal_CircleProgressBar.animated = true;
        //}));

        // try 3
        if (DownloadLC_Normal_CircleProgressBar.InvokeRequired)
        {
            DownloadLC_Normal_CircleProgressBar.BeginInvoke((MethodInvoker)delegate () { DownloadLC_Normal_CircleProgressBar.animated = true; });
        }
        else
        {
            DownloadLC_Normal_CircleProgressBar.animated = false;
        }

        // DOWNLOAD FILES THROUGH FTP BY CALLING A METHOD FROM A .cs FILE 
        // FROM THE PROJECT

        //UpdateMessage(false);
        //DownloadLC_Normal_CircleProgressBar.animated = false;
    }

CircleProgressBar永远不会动画。我错过了什么?我做错了什么,拜托? :(

编辑: 我遗漏了部分代码:

ftp ftpClient = new ftp("ftp://" + "192.168.1.200" + "/", "anonymous", "anonymous");
NetworkCredential credentials = new NetworkCredential("anonymous", "anonymous");
string url = "ftp://" + "192.168.1.200" + "/Documents and Settings/";
ftpClient.DownloadFtpDirectory(url, credentials, newDirectoryDownloadLocation);

2 个答案:

答案 0 :(得分:2)

最简单的选择之一是使用async / await:

async void DownloadLC_Normal_Button_Click(object sender, EventArgs e)
{
    DownloadLC_Normal_CircleProgressBar.animated = true;
    DownloadLC_Normal_Button.Enabled = false; // prevent further clicks
    await Task.Run(() =>
    {
        ...  // long running code, use `Invoke` to update UI controls
    });
    DownloadLC_Normal_CircleProgressBar.animated = false;
    DownloadLC_Normal_Button.Enabled = true;
}

答案 1 :(得分:2)

我假设您使用的是框架4.5 /更高版本或4.0,并且安装了Microsoft.Bcl.Async。

试一试:

private async void DownloadLC_Normal_Button_Click(object sender, EventArgs e)
{
    try
    {
        DownloadLC_Normal_Button.Enabled = false;
        DownloadLC_Normal_CircleProgressBar.animated = true;

        ftp ftpClient = new ftp("ftp://" + "192.168.1.200" + "/", "anonymous", "anonymous");
        NetworkCredential credentials = new NetworkCredential("anonymous", "anonymous");
        string url = "ftp://" + "192.168.1.200" + "/Documents and Settings/";

        //the code you post + change this line from:

        //ftpClient.DownloadFtpDirectory(url, credentials, newDirectoryDownloadLocation);

        //to: It makes the call be async

        await Task.Run(() => ftpClient.DownloadFtpDirectory(url, credentials, newDirectoryDownloadLocation));
    }
    finally
    {
        DownloadLC_Normal_CircleProgressBar.animated = false;
        DownloadLC_Normal_Button.Enabled = true;
    }
}