异常未在Task.Run包装方法中捕获

时间:2013-08-09 18:07:08

标签: c# exception-handling task-parallel-library async-await c#-5.0

异步等待C#5中的新功能。我正在使用一些基于任务的基本方法来探索异步等待和TPL。在下面的这个例子中,我正在调用一个超时为5秒的Web服务。如果超时到期,它应该抛出异常,所以我可以从方法返回false。但是,超时永远不会发生,或者可能会发生,但任务永远不会返回。

public static Task<bool> IsConnectedAsync()
{
    return Task.Run(() =>
    {
        try
        {
            using (WSAppService.AppService svc = new NCSoftware.Common.WSAppService.AppService(GetServiceUrl(WebService.app)){Timeout = 5000})
            {
                return svc.PingB();
            }
        }
        catch (Exception ex)
        {
            Logger.LogException(ex.Message, ex, "IsConnectedAsync");
        }    
        return false;
    });
}

如果你能帮忙解决如何正确处理这个问题,那么如果发生超时或者甚至更好,就会发生异常,任务确实会返回。

1 个答案:

答案 0 :(得分:1)

一般情况下,如果要包装Task.Run服务,则不应使用async。由于这是服务引用,您应该能够直接从服务公开async方法(返回Task),在这种情况下您可以使用:

public async static Task<bool> IsConnectedAsync()
{
    try
    {
         using (WSAppService.AppService svc = new NCSoftware.Common.WSAppService.AppService(GetServiceUrl(WebService.app)){Timeout = 5000})
         {
              return await svc.PingBAsync();
         }
     }
     catch (Exception ex)
     {
         Logger.LogException(ex.Message, ex, "IsConnectedAsync");
     }    
     return false;
}

如果你必须通过Task.Run换行(再次,这不建议,因为它通过线程池将同步代码转换为异步,通常由顶级用户更好地处理),你可以做:

public async static Task<bool> IsConnectedAsync()
{
    try
    {
       return await Task.Run(() =>
       {
         using (WSAppService.AppService svc = new NCSoftware.Common.WSAppService.AppService(GetServiceUrl(WebService.app)){Timeout = 5000})
         {
              return svc.PingB();
         }
       }
     }
     catch (Exception ex)
     {
         Logger.LogException(ex.Message, ex, "IsConnectedAsync");
         return false;
     }    
}