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

时间:2015-04-11 12:04:39

标签: c# .net multithreading asynchronous async-await

我正在尝试在不等待结果的情况下调用异步方法(在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);
}

正如你所看到的,我尝试了不同的方式;但没有他们给我我想要的东西。你有什么想法,对我有什么帮助?

2 个答案:

答案 0 :(得分:9)

  

我正在尝试调用异步方法(在ASP.NET Web API 2应用程序中)而不等待结果。

你确定这是你想做的吗?在ASP.NET上,如果你启动这样的独立工作(即,工作与HTTP请求无关),那么这项工作可能会在你不知情的情况下中止。在这种情况下,您的方法称为“日志”,因此可能是异步日志记录。所以你只想避免 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是。

答案 1 :(得分:0)

你做得对。

第一种方法就是你需要的。

// 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 });
        }