安排任务并继续,在C#

时间:2017-01-13 17:59:52

标签: c# async-await

我希望我的代码安排任务并立即进入ForeverRunningTaskAsync。这样StopForeverRunningTask在ForeverRunningTaskAsync正在进行5秒时执行:

private async void button_Click(object sender, RoutedEventArgs e)
{
  Task.Delay(5000).ContinueWith((t) => { StopForeverRunningTask(); }, CancellationToken.None);
  await ForeverRunningTaskAsync();
}

一切都在运行时正常运行。但是,编译器警告我在Task.Delay调用中错过了'await'。我不想等待,因为ForeverRunningTaskAsync必须立即启动,而不是在延迟之后。也许,有一种更优雅的方法来安排任务并立即进入后续代码?或者,我应该忽略警告吗?

编辑: StopForeverRunningTask实际上可以做任何事情。从答案中,我看到我应该为它提供更抽象的名称。它不一定会停止执行ForeverRunningTask。它可以设置一些标志,获取当前状态等(甚至在ForeverRunningTask运行时期间多次调用),因此使用CancellationToken不是一个选项。以下建议的WaitAll方法回答了我的问题。

3 个答案:

答案 0 :(得分:3)

您已经在代码中提供了一种方法来提示:CancellationToken

创建一个将在5秒内自动取消的CancellationToken

using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)))
{
    await ForeverRunningTaskAsync(cts.Token);
}

然后在ForeverRunningTaskAsync()方法中执行以下操作:

async Task ForeverRunningTaskAsync(CancellationToken cancellationToken)
{
    while (!cancellationToken.IsCancellationRequested)
    {
        // Do stuff, including passing cancellationToken on to anything
        // else that supports it
    }
}

如果这不适合您的代码或模型,还有其他类似方法可以使用取消令牌,但我建议以上是常态。

答案 1 :(得分:2)

忽略这种警告通常不是一个好主意。在某些情况下,它可能没有任何明显的直接影响(如在您的情况下),但它会使代码脆弱到周围的任何变化。

您拥有的其中一个选项是等待两个任务完成

private async void button_Click(object sender, RoutedEventArgs e)
{
  var stopper = Task.Delay(5000).ContinueWith((t) => { StopForeverRunningTask(); }, CancellationToken.None);
  var runner = ForeverRunningTaskAsync();
  await Task.WhenAll(stopper, runner);
}

答案 2 :(得分:1)

使用CancelationTokenSource。 5秒后,您的任务自动取消。


$_DVWA[ 'db_user' ]     = 'root';
$_DVWA[ 'db_password' ] = '';