首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >取消"warning CS4014:由于不等待此调用,当前方法的执行将继续...“

取消"warning CS4014:由于不等待此调用,当前方法的执行将继续...“
EN

Stack Overflow用户
提问于 2014-03-25 17:15:15
回答 8查看 62.7K关注 0票数 187

这不是"How to safely call an async method in C# without await"的副本。

如何才能很好地抑制以下警告?

警告CS4014:由于不等待此调用,因此在调用完成之前会继续执行当前方法。考虑将“await”运算符应用于调用结果。

一个简单的例子:

代码语言:javascript
复制
static async Task WorkAsync()
{
    await Task.Delay(1000);
    Console.WriteLine("Done!");
}

static async Task StartWorkAsync()
{
    WorkAsync(); // I want fire-and-forget 

    // more unrelated async/await stuff here, e.g.:
    // ...
    await Task.Delay(2000); 
}

我尝试过但不喜欢的东西:

代码语言:javascript
复制
static async Task StartWorkAsync()
{
    #pragma warning disable 4014
    WorkAsync(); // I want fire-and-forget here
    #pragma warning restore 4014
    // ...
}

static async Task StartWorkAsync()
{
    var ignoreMe = WorkAsync(); // I want fire-and-forget here
    // ...
}

更新了,由于original accepted answer已经被编辑,我已经更改了the one using C# 7.0 discards的接受答案,因为我不认为ContinueWith在这里是合适的。每当我需要记录“即发即忘”操作的异常时,我都会使用一种更复杂的方法proposed by Stephen Cleary here

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2017-12-13 17:59:11

在C# 7中,您现在可以使用discards

代码语言:javascript
复制
_ = WorkAsync();
票数 224
EN

Stack Overflow用户

发布于 2014-03-25 17:20:09

您可以创建一个扩展方法来防止该警告。扩展方法可以是空的,或者您可以在那里添加使用.ContinueWith()的异常处理。

代码语言:javascript
复制
static class TaskExtensions
{
    public static void Forget(this Task task)
    {
        task.ContinueWith(
            t => { WriteLog(t.Exception); },
            TaskContinuationOptions.OnlyOnFaulted);
    }
}

public async Task StartWorkAsync()
{
    this.WorkAsync().Forget();
}

但是,ASP.NET会计算正在运行的任务数,因此它不会使用上面列出的简单Forget()扩展,而是可能会失败,并出现异常:

异步模块或处理程序在异步操作仍处于挂起状态时完成。

在.NET 4.5.2中,可以通过使用HostingEnvironment.QueueBackgroundWorkItem来解决

代码语言:javascript
复制
public static Task HandleFault(this Task task, CancellationToken cancelToken)
{
    return task.ContinueWith(
        t => { WriteLog(t.Exception); },
        cancelToken,
        TaskContinuationOptions.OnlyOnFaulted,
        TaskScheduler.Default);
}

public async Task StartWorkAsync()
{
    System.Web.Hosting.HostingEnvironment.QueueBackgroundWorkItem(
        cancelToken => this.WorkAsync().HandleFault(cancelToken));
}
票数 125
EN

Stack Overflow用户

发布于 2016-02-04 12:57:56

我处理这件事的两种方式。

将其保存到丢弃变量(C# 7)

示例

_ = Task.Run(() => DoMyStuff()).ConfigureAwait(false);

由于在C# 7中引入了丢弃,我现在认为这比抑制警告要好。因为它不仅抑制了警告,而且明确了开火和遗忘的意图。

此外,编译器将能够在发布模式下对其进行优化。

只是抑制它

代码语言:javascript
复制
#pragma warning disable 4014
...
#pragma warning restore 4014

是一个很好的解决方案,可以用来“一发即忘”。

之所以存在此警告,是因为在许多情况下,您并不打算使用返回任务而不等待它的方法。当您确实想要触发并忘记时,隐藏警告是有意义的。

如果你记不住如何拼写#pragma warning disable 4014,那就让Visual Studio为你添加吧。按Ctrl+键。打开"Quick Actions“,然后打开"Suppress CS2014”

All all

仅仅为了抑制警告而创建一个多执行几次的方法是愚蠢的。

票数 48
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22629951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档