C#如何使用等待在没有阻止UI的任务中捕获异常 [英] C# How to catch exception in a Task without block UI using wait

查看:97
本文介绍了C#如何使用等待在没有阻止UI的任务中捕获异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

点击此按钮后,我就会看到此代码

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 awaits 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆