C#如何使用等待在没有阻止UI的任务中捕获异常 [英] C# How to catch exception in a Task without block UI using wait
问题描述
点击此按钮后,我就会看到此代码
I have this code in a button click
private async void btnStart_Click(object sender, EventArgs e)
{
Msg.Clear();
stopWatch.Reset();
timer.Start();
stopWatch.Start();
lblTime.Text = stopWatch.Elapsed.TotalSeconds.ToString("#");
progressBar.MarqueeAnimationSpeed = 30;
try
{
await Task.Factory.StartNew(() =>
{
try
{
Reprocess();
}
catch (Exception ex)
{
Msg.Add(new clsMSG(ex.Message, "Error", DateTime.Now));
timer.Stop();
stopWatch.Stop();
throw;
}
});
}
catch
{
throw;
}
}
这与Reprocess方法有关
and this on the Reprocess method
private void Reprocess()
{
try
{
clsReprocess reprocess = new clsReprocess(tbBD.Text, dtpStart.Value, 50000);
reprocess.Start(reprocess.BD);
}
catch
{
throw;
}
}
当Reprocess方法失败时,Task继续捕获,但是throw失败(catch内部catch(异常ex)),UI阻塞,直到reprocess.Start方法完成.我有两个问题:
when the Reprocess method fails, the Task goes to catch, but the throw fails (the throw inside catch (Exception ex)) and the UI blocks until the reprocess.Start method is completed. I have two questions:
- 首先:我该如何抓住按钮扣?"
- 第二:如何防止UI阻塞?
我希望你能理解我,对不起我的英语不好.
I hope you can understand me, sorry for my bad english.
推荐答案
您不应使用 Task.Factory.StartNew
; Task.Run
编写起来既安全又短.
You should not use Task.Factory.StartNew
; Task.Run
is both safer and shorter to write.
此外,您只能从UI线程访问UI控件.如果 Msg
与UI数据绑定,则这可能是导致您遇到问题的原因.即使不是这样,您也不想从多个线程访问不受保护的集合(例如 List< clsMSG>
).
Also, you can only access UI controls from the UI thread. This may be the cause of the problems you're seeing, if Msg
is data-bound to the UI. Even if it's not, you don't want to access unprotected collections (e.g., List<clsMSG>
) from multiple threads.
同时应用这两个准则会将代码减少为:
Applying both of these guidelines reduces the code to:
private async void btnStart_Click(object sender, EventArgs e)
{
Msg.Clear();
stopWatch.Reset();
timer.Start();
stopWatch.Start();
lblTime.Text = stopWatch.Elapsed.TotalSeconds.ToString("#");
progressBar.MarqueeAnimationSpeed = 30;
try
{
await Task.Run(() => Reprocess());
}
catch (Exception ex)
{
Msg.Add(new clsMSG(ex.Message, "Error", DateTime.Now));
timer.Stop();
stopWatch.Stop();
throw;
}
}
如果 Reprocess
引发异常,则该异常将放置在 Task.Run
返回的任务上.当您的代码等待
完成该任务时,该异常将重新引发并被捕获在 catch
中.在 catch
的末尾,代码将重新引发该异常( throw;
).
If Reprocess
throws an exception, that exception will be placed on the task returned from Task.Run
. When your code await
s that task, that exception is re-raised and caught in the catch
. At the end of the catch
, the code will re-raise that exception (throw;
).
这篇关于C#如何使用等待在没有阻止UI的任务中捕获异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!