C# 延迟然后执行任务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19703740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 15:40:23  来源:igfitidea点击:

Delay then execute Task

c#.netasynchronoustask-parallel-library

提问by David

Quick question, I want to waita second before launchingan async taskwithout a return value.
Is this the right way to do it?

快速提问,我想在启动没有返回值的异步任务之前等待一秒钟。 这是正确的方法吗?

Task.Delay(1000)
    .ContinueWith(t => _mq.Send(message))
    .Start();

What happens to exceptions?

异常会发生什么?

采纳答案by svick

First of all, Start()only works on the (very rare) Tasks that were created using the Taskconstructor (e.g. new Task(() => _mq.Send(message))). In all other cases, it will throw an exception, because the Taskis already started or waiting for another Task.

首先,Start()仅适用于Task使用Task构造函数(例如new Task(() => _mq.Send(message)))创建的(非常罕见的)s 。在所有其他情况下,它会抛出异常,因为Task已经启动或正在等待另一个Task

Now, probably the best way to do this would be to put the code into a separate asyncmethod and use await:

现在,最好的方法可能是将代码放入一个单独的async方法中并使用await

async Task SendWithDelay(Message message)
{
    await Task.Delay(1000);
    _mq.Send(message);
}

If you do this, any exception from the Send()method will end up in the returned Task.

如果这样做,该Send()方法的任何异常都将在返回的Task.

If you don't want to do that, using ContinueWith()is a reasonable approach. In that case, exception would be in the Taskreturned from ContinueWith().

如果您不想这样做,使用ContinueWith()是一种合理的方法。在这种情况下,异常将在Task返回的 from 中ContinueWith()

Also, depending on the type of _mq, consider using SendAsync(), if something like that is available.

此外,根据 的类型,如果有类似的东西_mq,请考虑使用SendAsync()

回答by Gusdor

You will be able to observe any exceptions if you Waitfor the task.

如果您Wait执行任务,您将能够观察到任何异常。

Unhandled exceptions that are thrown by user code that is running inside a task are propagated back to the joining thread, except in certain scenarios that are described later in this topic. Exceptions are propagated when you use one of the static or instance Task.Wait or Task.Wait methods, and you handle them by enclosing the call in a try-catch statement.

由在任务内运行的用户代码引发的未处理异常将传播回加入线程,但在本主题后面描述的某些情况下除外。当您使用静态或实例 Task.Wait 或 Task.Wait 方法之一并通过将调用包含在 try-catch 语句中来处理它们时,会传播异常。

Excerpt from Exception Handling (Task Parallel Library)

异常处理摘录(任务并行库)

Be careful with timings. Tasks use a scheduler and are not guaranteed to start when your say 'go'. You code will guarantee at least1000ms delay after telling it to Startbut it is not guaranteed to be 1000ms exactly.

小心时间。任务使用调度程序并且不能保证在您说“开始”时开始。您的代码将保证告诉它后至少有1000 毫秒的延迟,Start但不能保证准确地为 1000 毫秒。

回答by Attila

You can catch any exception thrown in the Task if you Wait for the Task to finish:

如果您等待任务完成,您可以捕获任务中抛出的任何异常:

Be aware of that your Exception thrown in the Task is going to be the inner one

请注意,您在 Task 中抛出的异常将是内部异常

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Task task = Task.Delay(1000)
                .ContinueWith(t => Program.throwsException());

            task.Wait();     
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception:" + ex.Message); // Outputs: Exception:One or more errors occurred.
            Console.WriteLine("Inner exception:" + ex.InnerException.Message); // Outputs: Exception:thrown
        }
        Console.ReadKey();

    }
    static void throwsException()
    {
        Console.WriteLine("Method started");
        throw new Exception("thrown");
    }
}