简体   繁体   中英

Problems with handling exceptions from async method with tasks

I hope you can help me with that problem.

I have a method that does specific actions, for example, I am sending a HttpWebRequest. There I can get a WebException , so I put it in a Try-Catch-block to rethrow exceptions for more specific exception messages.

Like that: (This is in a method called doWebRequest )

try 
{
   // HttpWebRequest here
}

catch (WebException ex)
{
  throw new WebException(String.Format("My special additional message {0}", ex.Message);
}

Well, so this works, when I call this function normally. But now I want an async way to do this. What I made to call this method in an async method:

public void DoRequestAsync() 
{
   Task internalRequest = new Task(doWebRequest);
   internalRequest.ContinueWith(InternalUpdateSearchExceptionHandler, TaskContinuationOptions.OnlyOnFaulted);
   internalRequest.Start();
}

So this makes a new task and then calls the method doWebRequest async. To handle errors now, because I know it is different on async, I made this handler, which you can also see in internalRequest.ContinueWith . Looks like that:

private void InternalUpdateSearchExceptionHandler(Task task)
{
  var ex = task.Exception;
  if (ex.InnerException is WebException)
  {
     if ((ex.InnerException as WebException).Status == WebExceptionStatus.ProtocolError)
     {
        throw new WebException(ex.InnerException.Message);
     }

     else
     {
        throw new Exception("There was no response from the server.");
     }
  }
}

But this is not executing any exceptions. I don't know why. At first I thought, this is because it cannot take the InnerException as a WebException, or would that work? If not, please tell me what to do here. But even when I throw an exception without any queries here, it did not throw any exceptions while debugging. Why is that?

Help is appreciated. When something is not clear, ask me. ;)

Your continuation is throwing an exception, but when that continuation throws an exception all that happens is the Task that represents that continuation is marked as Faulted with the given exception as its Exception. You currently are ignoring the task created by calling ContinueWith , so there is nothing to observe this exception.

DoRequestAsync likely shouldn't be void ; rather it should return a Task , specifically the one created by calling ContinueWith , so that whoever calls this method can observe any exceptions thrown.

Also note that you could do this much more simply using async :

public async Task DoRequestAsync() 
{
    try 
    {
        var content = await new WebClient()
            .DownloadStringTaskAsync("address");
    }
    catch (WebException ex)
    {
      throw new WebException(String.Format("My special additional message {0}", ex.Message);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM