在不等待的情况下调用异步方法

Calling an async method without awaiting

我正在尝试调用异步方法(在 ASP.NET Web API 2 应用程序中)而不等待结果。我的意思是我想让主线程继续执行并且不等待被调用的方法完成。我正在尝试这个片段:

// The async method:
private static async Task LogAsync(Exception exception, string ip, MethodBase method, object parameters) {
    // some stuff 
}

// The caller methods:
public static void Log1(Exception exception, object parameters) {
    LogAsync(exception, ip, method, parameters);
}
public static void Log2(Exception exception, object parameters) {
    Task.Factory.StartNew(() => LogAsync(exception, ip, method, parameters));
}
public static async void Log3(Exception exception, object parameters) {
    await LogAsync(exception, ip, method, parameters).ConfigureAwait(true);
}
public static async void Log4(Exception exception, object parameters) {
    // I've tried even this one:
    await LogAsync(exception, ip, method, parameters).ConfigureAwait(false);
}

如你所见,我尝试了不同的方法;但他们中没有一个能给我我想要的。你有什么想法,对我有什么帮助吗?

你没看错。

第一种方法是你需要的。

// The caller methods:
public static void Log1(Exception exception, object parameters) {
    LogAsync(exception, ip, method, parameters);
}

问题可能出在其他地方。你如何测试这个?

Log1 的 LogAsync 将在不同的线程上执行。这就像火了,忘记了这正是您所需要的。

编辑: 尝试将 LogAsync 方法更改为:

// The async method:

        private static void LogAsync(Exception exception, string ip, MethodBase method, object parameters) {
    Task.Factory.StartNew(delegate {
            // some stuff });
        }

I'm trying to call an async method (in an ASP.NET Web API 2 app) without awaiting for the result.

您确定这是您要执行的操作吗?在 ASP.NET,如果您像这样开始独立工作(即工作 与 HTTP 请求 无关),那么该工作可能会在您不知情的情况下中止。在这种情况下,您的方法称为 "log",因此大概它们是异步记录的。所以你只想避免 await 如果偶尔丢失日志是完全可以接受的。如果您希望日志可靠,则需要保留 await。你来电。

假设偶尔丢失日志是可以的,那么您至少应该将工作注册到 ASP.NET 运行时。如果您使用的是 .NET 4.5.2,则可以使用 HostingEnvironment.QueueBackgroundWorkItem,例如:

public static void Log(Exception exception, object parameters) {
  HostingEnvironment.QueueBackgroundWorkItem(_ =>
      LogAsync(exception, ip, method, parameters));
}

如果您使用的是旧版本的 .NET(4.5 或 4.5.1),您可以使用我的 AspNetBackgroundTasks library:

public static void Log(Exception exception, object parameters) {
  BackgroundTaskManager.Run(() =>
      LogAsync(exception, ip, method, parameters));
}

两者之间的语义略有不同(我有一篇文章 on my blog),但它们都将工作注册到 ASP.NET 运行时,所以至少它不是 完全Task.Factory.StartNewTask.Run 一样不可靠。