2015-08-31 55 views
4

在下面的方法中,当在TRY块中抛出异常时,它被吞下。我怎样才能让它抛出异常,以便它被写入以登录catch块?日志编写器工作正常。谢谢!任务吞下抛出的异常

public static bool MonitorQueueEmptyTask(string queueName, CancellationTokenSource tokenSource) 
{ 
    try 
    { 
     Task<bool> task = Task.Factory.StartNew<bool>(() => 
     { 
      while (!QueueManager.IsQueueEmpty(queueName)) 
      { 
       if (tokenSource.IsCancellationRequested) 
       {        
        break; 
       } 

       Thread.Sleep(5000); 
       throw new Exception("Throwing an error!"); //THIS THROW IS SWALLOWED -- NO LOG WRITTEN ON CATCH 
      }; 

      return true; 

     }, tokenSource.Token); 
    } 
    catch (Exception ex) 
    { 
     WriteExceptionToLog(ex.Stack); //it's not that this method doesn't work. it works fine. 

     return false; 
    } 

    return true; 
} 
+3

MSDN - [如何:处理由任务引发的异常(https://msdn.microsoft.com/en-us/library/dd537614.aspx) –

+0

您能放置的try/catch在任务块? – IllidanS4

+0

这不能工作,因为当外线程退出try时任务可能没有完成。 – usr

回答

6

如果您想开火并忘记,可以使用ContinueWith附加延续。目前的try-catch根本无法帮到你,因为例外被封装在Task之内。如果这是“射后不理”,比你可以登录异常:

public static Task MonitorQueueEmptyTask(
         string queueName, CancellationTokenSource tokenSource) 
{ 
    return Task.Factory.StartNew<bool>(() => 
    { 
     while (!QueueManager.IsQueueEmpty(queueName)) 
     { 
      if (tokenSource.IsCancellationRequested) 
      {        
       break; 
      } 

      Thread.Sleep(5000); 
      throw new Exception("Throwing an error!"); 
     }; 
    }, tokenSource.Token, TaskCreationOptions.LongRunning).ContinueWith(faultedTask => 
    { 
     WriteExceptionToLog(faultedTask.Exception); 
    }, TaskContinuationOptions.OnlyOnFaulted); 
} 

这,反过来,会不会它抛出后传播异常,但会提供一种机制来记录错误。如果您希望由于某种原因重新抛出此错误,则可以在您的配置中注册TaskScheduler.UnobservedTaskException并设置ThrowUnobservedTaskExceptions enabled="true"。注意这个ContinueWith,因为一旦你看到task.Exception属性,它会考虑异常“处理”。

+0

谢谢我的朋友! – user1013388

+0

@ user1013388欢迎:) –

+0

请注意,您必须专门访问task.Exception属性以处理异常。 – Craig

2

异常不被吞咽;只是它不会在执行try/catch块的线程上发生,而是在单独的任务线程上发生。

如果您没有观察到任务的结果或异常,那么当任务最终被垃圾回收时,它将抛出一个异常,表示该任务未被遵守。除非您通过处理TaskScheduler.UnobservedTaskException来解决这个问题,否则会导致程序崩溃。

0

我也有这个问题,我真的不喜欢的App.config的整体思路,这样可以提供另一种解决方案,以防止异常消失:)

保存例外接了任务后,把它。运行已完成,例如

private async void Function() { 
    Exception save_exception = null; 

    await Task.Run(() => { 
     try { 
      // Do Stuff 
     } catch (Exception ex) { 
      save_exception = ex; 
     } 
    }).ContinueWith(new Action<Task>(task => { 
     if (save_exception != null) 
      throw save_exception; 

     // Do Stuff 
    })); 
}