C# How to catch exception in a Task without block UI using wait

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-13 18:39:41

问题


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

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. I have two questions:

  • First: How can I catch the throw in the catch of my button?
  • Second: How can I prevent the UI blocks?

I hope you can understand me, sorry for my bad english.


回答1:


You should not use Task.Factory.StartNew; Task.Run is both safer and shorter to write.

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;
  }
}

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;).



来源:https://stackoverflow.com/questions/35303451/c-sharp-how-to-catch-exception-in-a-task-without-block-ui-using-wait

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!