任务吞下抛出的异常

use*_*388 6 .net c# exception task task-parallel-library

在下面的方法中,当在TRY块中抛出异常时,它被吞下.如何让它抛出异常,以便写入catch块中的log?日志编写器工作正常.谢谢!

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;
}
Run Code Online (Sandbox Code Playgroud)

Yuv*_*kov 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); 
}
Run Code Online (Sandbox Code Playgroud)

反过来,这不会在抛出异常后传播异常,但会提供记录错误的机制.如果由于某种原因需要重新抛出,可以注册TaskScheduler.UnobservedTaskException并设置 ThrowUnobservedTaskExceptions enabled="true"配置.请注意这一点ContinueWith,因为一旦你查看task.Exception属性,它将考虑异常"处理" .