Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何防止异步方法阻塞UI?_C#_Multithreading_User Interface_Asynchronous_Async Await - Fatal编程技术网

C# 如何防止异步方法阻塞UI?

C# 如何防止异步方法阻塞UI?,c#,multithreading,user-interface,asynchronous,async-await,C#,Multithreading,User Interface,Asynchronous,Async Await,因此,我正在编写一个方法,该方法应该处理大量字符串,并为处理的每个字符串更新UI。为此,我使用了asyncwait模式,它使用一个进度报告器向主线程报告一个字符串,该字符串应该在主线程中更新。 问题是:它不起作用。UI被阻塞,就好像方法是同步运行的,即使我使用了wait关键字。 我的代码是这样的: private async Task ProcessFile(string filePath, IProgress<string> progress) { stri

因此,我正在编写一个方法,该方法应该处理大量字符串,并为处理的每个字符串更新UI。为此,我使用了
asyncwait
模式,它使用一个进度报告器向主线程报告一个字符串,该字符串应该在主线程中更新。 问题是:它不起作用。UI被阻塞,就好像方法是同步运行的,即使我使用了wait关键字。 我的代码是这样的:

private async Task ProcessFile(string filePath, IProgress<string> progress)
    {
        string[] LinesToProcess = File.ReadAllLines(filePath);
        int LineCount = Buffer.Count();

        await Task.Factory.StartNew(() =>
       {
           for (int i = 0; i < Buffer.Count(); i++)
           {
               //Do actual processing here
               progress.Report(string.Format("Lines processed: {0} / {1}", i, LineCount));
           }
       });
    }
最后,这里是与RunTask()任务相关的按钮回调:

private async void Button_Click(object sender, EventArgs e)
    {
        await RunTask();
    }
为了便于阅读,我简化了代码。非常感谢您的帮助。谢谢大家!

我可以看到两个选项:

  • 您处理许多行的速度如此之快,以至于UI线程一直忙于更新,没有时间实际显示结果。要解决这个问题,不要报告每行的进度,只报告每100行、每1000行或每行的数量是否适合您。或者,您可以基于时间报告进度,例如每秒一次。但这需要更复杂的代码
  • 您遇到了
    Task.Factory.StartNew()
    的问题,它在UI线程上运行,因为这是当前的
    。虽然我在你的代码中没有看到任何迹象表明这种情况,所以我认为这种可能性不大。但是为了安全起见,您应该使用
    Task.Run()
    。有关更多信息,请阅读

  • File.ReadAllLines(文件路径)就是要做到这一点,阅读所有的行,所以如果有分配的行,你最好逐行阅读。这可能会有帮助。我是Async的新手你有没有尝试过将ConfigureWait(false)添加到ProcessFile函数调用中,我看到过很多次UI块就是因为这个原因。为什么要投反对票?虽然我同意
    Task.Run
    更好,但用户界面阻塞问题几乎肯定是由(1)引起的。这是因为。所以我尝试了两种选择,但似乎都不能解决问题。每运行大约100次
    for
    循环更新一次UI会使代码运行得更快,但UI仍然会被阻塞。此外,我还尝试使用调试器,如果我在
    ProcessedLabel.Text=newReport行,我看到,通过跨过它,该行会不断被调用,即使我将其设置为每100次更新一次@CRefice然后尝试1000,甚至更多。看起来您的处理速度非常快,您必须基于此设置数字。如果您在调试器中看到行处于活动状态,但它没有任何效果,那么很可能只是调试器的一个小故障。
    
    private async void Button_Click(object sender, EventArgs e)
        {
            await RunTask();
        }