C#如何使用wait在没有阻止UI的情况下捕获任务中的异常

时间:2016-02-09 22:29:22

标签: c# asynchronous try-catch task

我点击了按钮

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方法

private void Reprocess()
    {
        try
        {
            clsReprocess reprocess = new clsReprocess(tbBD.Text, dtpStart.Value, 50000);
            reprocess.Start(reprocess.BD);
        }
        catch
        {
            throw;
        }
    }

当Reprocess方法失败时,Task进入catch,但是throw失败(throw inside catch(Exception ex))和UI阻塞,直到reprocess.Start方法完成。 我有两个问题:

  • 首先:我怎样才能抓住我的按钮?
  • 第二:如何阻止UI阻止?

我希望你能理解我,抱歉我的英语不好。

1 个答案:

答案 0 :(得分:1)

你不应该使用Task.Factory.StartNew;写Task.Run更安全,更短。

此外,您只能从UI线程访问UI控件。如果Msg与UI绑定数据,这可能是您遇到问题的原因。即使不是,您也不想从多个线程访问未受保护的集合(例如,List<clsMSG>)。

应用这两个指南会将代码缩减为:

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返回的任务上。当您的代码await成为该任务时,该异常将重新引发并被catch捕获。在catch的末尾,代码将重新引发该异常(throw;)。