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

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

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

我试图在不等待结果的情况下调用异步方法(在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库 :

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

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

你做得对。

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

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