[英]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;
}
}
and this on the Reprocess method 这是在Reprocess方法上
private void Reprocess()
{
try
{
clsReprocess reprocess = new clsReprocess(tbBD.Text, dtpStart.Value, 50000);
reprocess.Start(reprocess.BD);
}
catch
{
throw;
}
}
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. 当Reprocess方法失败时,Task会继续捕获,但是throw失败(catch内部的throw(异常ex)),UI会阻塞,直到reprocess.Start方法完成为止。 I have two questions: 我有两个问题:
I hope you can understand me, sorry for my bad english. 我希望你能理解我,对不起我的英语不好。
You should not use Task.Factory.StartNew
; 您不应该使用Task.Factory.StartNew
; Task.Run
is both safer and shorter to write. Task.Run
更安全,编写更短。
Also, you can only access UI controls from the UI thread. 另外,您只能从UI线程访问UI控件。 This may be the cause of the problems you're seeing, if Msg
is data-bound to the UI. 如果Msg
与UI数据绑定,则可能是导致您遇到问题的原因。 Even if it's not, you don't want to access unprotected collections (eg, List<clsMSG>
) from multiple threads. 即使不是,您也不想从多个线程访问不受保护的集合(例如List<clsMSG>
)。
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;
}
}
If Reprocess
throws an exception, that exception will be placed on the task returned from Task.Run
. 如果Reprocess
抛出异常,则该异常将放置在Task.Run
返回的任务上。 When your code await
s that task, that exception is re-raised and caught in the catch
. 当您的代码await
该任务执行时,该异常将重新引发并被catch
。 At the end of the catch
, the code will re-raise that exception ( throw;
). 在catch
结束时,代码将重新引发该异常( throw;
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.