1

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.

8
  • Why did you insert those catch handlers that do nothing? I always wondered why people are doing this hence I'm asking. Commented Feb 9, 2016 at 22:34
  • @usr stackoverflow.com/questions/8009773/… Commented Feb 9, 2016 at 22:38
  • I'm catching the error (on the Task) for show in a DatagridView, the problem is that the system continues doing the Reprocess method, after that catch Commented Feb 9, 2016 at 22:39
  • System catch an exception (on reprocess.Start(reprocess.BD)) Commented Feb 9, 2016 at 22:45
  • 1
    Please cleanup your code, get rid of unnecessary try .. catch { throw; } blocks, use Task.Run instead of Task.Factory.StartNew, move your catch (Exception ex) {...} block below the await, and don't EVER access any UI controls from a background thread. Commented Feb 10, 2016 at 0:02

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

2 Comments

Should I disable Just My Code? because if it's enabled when Reprocess throws the exception the catch on the button doesn't catch it, I need to press F5 to continue.
@AbdelPosada: I think it's fine the way it is.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.