防止形式冻结

Kai*_*Kai 3 .net c# multithreading winforms

我想下载一张图片然后在图片框中显示.

起初我喜欢这样:

WebClient client = new WebClient();
client.DownloadFile(url, localFile);
pictureBox2.Picture = localFile;
Run Code Online (Sandbox Code Playgroud)

但这并不完美,因为在下载执行的时候,应用程序有点冷冻.

然后我改为:

public class ParamForDownload
{
    public string Url { get; set; }
    public string LocalFile { get; set; }
}
ParamForDownload param = new ParamForDownload()
        {
            Url = url,
            LocalFile = localFile
        };

      ThreadStart starter = delegate { DownloadMap (param); };
        new Thread(starter).Start();

        pictureBox2.Picture = localFile;



    private static void DownloadMap(ParamForDownload p) 
    {
        WebClient client = new WebClient();
       client.DownloadFile(p.Url, p.LocalFile);
    }
Run Code Online (Sandbox Code Playgroud)

但现在我必须做一些类似"等待线程结束"的事情,因为文件是在线程中访问的,同时也是通过DownloadMap方法将文件下载到文件中.

什么是解决这个问题最好的等待?

Llo*_*ell 13

基本上,最初发生的是UI线程正在完成下载,并且因为它正在解决这个问题,它无法刷新或绘制(同步工作).现在发生的是你正在启动线程然后UI线程继续,然后尝试将本地文件(尚未完成下载)分配到图片框.您应该尝试以下任一方法:

您应该使用后台工作程序来完成下载任务.

它有非常方便的事件.DoWork,您可以在其中开始下载.

还有一个RunWorkerCompleted事件,在Work完成时触发.你可以在哪里设置图像(pictureBox2.Picture = localFile;).

这绝对值得一试,我认为这是完成你想要实现的目标的最合适的方式.

要么

如果你想坚持使用线程.完成后,您可以取出图像分配Thread.Start(),并将其放入您的工作线程功能:

private delegate void MyFunctionCaller();

private static void DownloadMap(ParamForDownload p) 
{
    WebClient client = new WebClient();
   client.DownloadFile(p.Url, p.LocalFile);
    DownloadMapComplete(p);
}

private void DownloadMapComplete(ParamForDownload p)
{
if (InvokeRequired == true)
  {
  MyFunctionCaller InvokeCall = delegate { DownloadMapComplete(p); };
  Invoke(InvokeCall);
  }
else
  {
  pictureBox2.Picture = p.LocalFile;
  }
}
Run Code Online (Sandbox Code Playgroud)