加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 异步进度条更新

发布时间:2020-12-15 06:14:48 所属栏目:百科 来源:网络整理
导读:我试图使用异步等待根据复制操作更新我的WinForm上的进度条,但进度条只会在复制功能完成时更新,然后抛出一个无法更新的异常,因为它不是在同一个线程上? 复制功能不需要与UI交互,但Progress功能可以. 虽然UI没有被阻止,但是看起来异步部分正在按预期工作,它
我试图使用异步等待根据复制操作更新我的WinForm上的进度条,但进度条只会在复制功能完成时更新,然后抛出一个无法更新的异常,因为它不是在同一个线程上?

复制功能不需要与UI交互,但Progress功能可以.

虽然UI没有被阻止,但是看起来异步部分正在按预期工作,它只是与UI线程进行交互.

long fileProgress = 0;
long totalProgress = 0;
bool complete = false;

CopyFileEx.CopyFileCallbackAction callback(FileInfo source,FileInfo destination,object state,long totalFileSize,long totalBytesTransferred)
{
      fileProgress = totalBytesTransferred;
      totalProgress = totalFileSize;
      return CopyFileEx.CopyFileCallbackAction.Continue;
}

async Task Progress()
{
      await Task.Run(() =>
      {
           while (!complete)
           {
                if (fileProgress != 0 && totalProgress != 0)
                {
                     fileProgressBar.Value = (int)(fileProgress / totalProgress) * 100;
                }
           }
      });
}

private async void startButton_Click(object sender,EventArgs e)
{
      Copy();
      await Progress();
      MessageBox.Show("Done");
}

void Copy()
{
      Task.Run(() =>
      {
           CopyFileEx.FileRoutines.CopyFile(new FileInfo(@"C:_USBFear.rar"),new FileInfo(@"H:Fear.rar"),CopyFileEx.CopyFileOptions.All,callback,null);
           complete = true;
      });
}

解决方法

> async / await就是在处理I / O时没有阻塞线程 – 任何线程.在Task.Run()中放置一个阻塞I / O调用(就像你在Copy()中所做的那样)并没有避免阻塞 – 它只是创建了一个其他线程稍后会选择的任务,只是发现它本身被阻塞了它命中了阻塞的CopyFileEx.FileRoutines.CopyFile()方法.
>您收到该错误是因为您没有正确使用async / await(无论上述情况如何).考虑哪个线程正在尝试修改UI对象fileProgressBar:随机线程池线程获取您在Task.Run()上创建的任务获取执行fileProgressBar.Value = …,这显然会抛出.

这是避免这种情况的一种方法:

async Task Progress()
{
      await Task.Run(() =>
      {
           //A random threadpool thread executes the following:
           while (!complete)
           {
                if (fileProgress != 0 && totalProgress != 0)
                { 
                    //Here you signal the UI thread to execute the action:
                    fileProgressBar.Invoke(() => 
                    { 
                        //This is done by the UI thread:
                        fileProgressBar.Value = (int)(fileProgress / totalProgress) * 100 
                    });
                }
           }
      });
}

private async void startButton_Click(object sender,EventArgs e)
{
      await Copy();
      await Progress();
      MessageBox.Show("Done");  //here we're on the UI thread.
}

async Task Copy()
{
    //You need find an async API for file copy,and System.IO has a lot to offer.
    //Also,there is no reason to create a Task for MyAsyncFileCopyMethod - the UI
    // will not wait (blocked) for the operation to complete if you use await:
    await MyAsyncFileCopyMethod();
    complete = true;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读