任务吞噬抛出的异常 [英] Task swallows the exception thrown

查看:138
本文介绍了任务吞噬抛出的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的方法中,当TRY块中抛出异常时,它被吞噬。如何使它抛出异常,以便它被写入登录catch块?日志记录器工作正常。谢谢!

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

Thread.Sleep(5000);
抛出新的异常(抛出一个错误!); //这个OW ED ED - ;;;;;
};

return true;

},tokenSource.Token);
}
catch(Exception ex)
{
WriteExceptionToLog(ex.Stack); //这不是这个方法不起作用。它工作正常

返回false;
}

返回true;
}


解决方案

忘了,你可以使用 ContinueWith 附加一个延续。目前的 try-catch 根本不会帮助您,因为例外是封装在任务之内。如果这是fire and forget,你可以记录例外:

  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异常(抛出错误!);
};
},tokenSource.Token,TaskCreationOptions.LongRunning).ContinueWith(faultedTask =>
{
WriteExceptionToLog(faultedTask。异常);
},TaskContinuationOptions.OnlyOnFaulted);
}

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

In the method below, when an exception is thrown in the TRY block, it is being swallowed. How can I make it throw the exception so that it gets written to log in the catch block? The log writer works fine. Thanks!

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;
}

解决方案

If you want to fire and forget, you can attach a continuation using ContinueWith. The current try-catch will not help you at all, as the exception is encapsulated inside the Task. If this is "fire and forget", than you can log the exception:

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

This, in turn, will not propagate the exception after it's thrown, but will provide a mechanism to log the error. If you want this to be re-thrown for some reason, you can register to TaskScheduler.UnobservedTaskException and set ThrowUnobservedTaskExceptions enabled="true" in your configuration. Note this ContinueWith, since it will consider the exception "handled" once you look at the task.Exception property.

这篇关于任务吞噬抛出的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆