Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 捕获任务(task.Delay())执行的操作的异常_C#_.net - Fatal编程技术网

C# 捕获任务(task.Delay())执行的操作的异常

C# 捕获任务(task.Delay())执行的操作的异常,c#,.net,C#,.net,我构建了一种计划任务,它将在计划日期执行操作。我使用了Task.Delay(Delay).ContinueWith(action.Invoke()) 有时操作会抛出异常,但仍然无法传播此异常以正确注册它 在我的示例中,a创建了一个包含三个文本的列表,空文本将抛出一个异常,但是我无法在try..catch块中捕获该异常 class Program { static async Task Main() { var texts = new

我构建了一种计划任务,它将在计划日期执行操作。我使用了
Task.Delay(Delay).ContinueWith(action.Invoke())

有时操作会抛出异常,但仍然无法传播此异常以正确注册它

在我的示例中,a创建了一个包含三个文本的列表,空文本将抛出一个异常,但是我无法在try..catch块中捕获该异常

class Program
    {
        static async Task Main()
        {
            var texts = new List<string>() { "text 1", null, "text 2"};
            foreach (var text in texts)
            {
                var scheduleDate = DateTime.UtcNow.AddSeconds(10);
                try
                {
                    ReminderControl.AddReminder(Print, text, scheduleDate);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error to schedule the text {text} to be print on {scheduleDate:s}. ex: {ex.Message}");
                }                
            }

            while (true)
            {
                await Task.Delay(2000);
                Console.WriteLine("Doing other things...");
            }
        }

        static void Print(object text)
        {
            if (text is null)
                throw new ArgumentNullException(); \\thrown , but not propagated out

            Console.WriteLine(text);
        }
    }

    public class ReminderControl
    {
        public static void AddReminder(Action<object> remiderCallback, object context, DateTime scheduleDate)
        {
            var delay = scheduleDate.Subtract(DateTime.UtcNow);
            Task.Delay(delay)
              .ContinueWith(t => remiderCallback.Invoke(context));
            //.ContinueWith(t => throw t.Exception, TaskContinuationOptions.OnlyOnFaulted); even with this line the exception still does not propagate
        }
    }
类程序
{
静态异步任务Main()
{
var text=new List(){“text 1”,null,“text 2”};
foreach(文本中的var文本)
{
var scheduleDate=DateTime.UtcNow.AddSeconds(10);
尝试
{
提醒控制。添加提醒(打印、文本、日程日期);
}
捕获(例外情况除外)
{
Console.WriteLine($“计划在{scheduleDate:s}.ex:{ex.Message}上打印文本{text}时出错);
}                
}
while(true)
{
等待任务。延迟(2000);
Console.WriteLine(“做其他事情…”);
}
}
静态无效打印(对象文本)
{
如果(文本为空)
抛出新ArgumentNullException();\\抛出,但未传播出去
控制台写入线(文本);
}
}
公共类提醒控件
{
public static void addrementer(操作remiderCallback、对象上下文、DateTime scheduleDate)
{
var delay=scheduleDate.Subtract(DateTime.UtcNow);
任务。延迟(延迟)
.ContinueWith(t=>remiderCallback.Invoke(context));
//.ContinueWith(t=>throw t.Exception,TaskContinuationOptions.OnlyOnFaulted);即使使用此行,异常仍然不会传播
}
}
在任务中使用等待更新。延迟

await ReminderControl.AddReminder(Print, text, scheduleDate);

public static async Task AddReminder(Action<object> remiderCallback, object context, DateTime scheduleDate)
{
    var delay = scheduleDate.Subtract(DateTime.UtcNow);
    await Task.Delay(delay);
    remiderCallback.Invoke(context);
}
等待提醒控制。添加提醒(打印、文本、日程日期);
公共静态异步任务AddReminder(操作remiderCallback、对象上下文、DateTime scheduleDate)
{
var delay=scheduleDate.Subtract(DateTime.UtcNow);
等待任务。延迟(延迟);
调用(上下文);
}
在此之后,
try..catch
块捕获了异常,但是,
“正在做其他事情…”
停止打印,可能正在等待
添加提醒
完成


我希望保持异步打印
“做其他事情…”

如果希望异常从任务中正确出现,则需要使用完整的
异步
编译器构造。将表达式替换为:

await Task.Delay(delay);
action.Invoke();

将它放入一个
async
函数中,该函数返回某种类型的
任务
,并确保等待返回的任务。等待会让你抓到例外情况。

谢谢。在任务中添加wait.Delay和wait后,我的主线程中的“正在做其他事情…”停止打印,可能是在等待addrementer。猜猜看?猜猜看,你的分析是正确的。如果您想询问如何使它仍然是异步的,同时保持
try
catch
围绕它,请将
try
catch
块和等待的
addremememememplier
调用一个单独的
async
函数,并在不等待的情况下调用该函数。是的,没错,我需要继续在外部异步工作。添加提醒类似于“开火并忘记”,但如果有任何问题,请记录下来。关于你的上一个建议,我对这两个建议有点困惑。
try..catch
。所以我正在努力实现它。谢谢。我失败得很惨,我相信我不明白你的解决办法。你能用这个更新你的答案吗,或者看看我错在哪里@拉斐尔·皮门塔,试试这个:。总的来说,这不是一个好的解决方案,更好的解决方案包括一个依赖注入日志服务,该服务在未处理的异常情况下被调用,但此实现更符合您的项目。使用第二种方法,您可以收集由
addrementer
返回的所有任务,然后使用
wait Task等待它们全部完成。当所有(任务)
完成时,您是否可以将try-catch块放在
addrementer
方法中,并使用wait在那里处理事情,但是在更高的层次上,不要使用wait,这样你就可以继续做你想做的其他事情了?是的。这是可能的,但是当AddRemembers操作抛出异常时,仍然需要将其传播出去。