Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
294 views
in Technique[技术] by (71.8m points)

c# - Calling an async method without awaiting

I'm trying to call an async method (in an ASP.NET Web API 2 app) without awaiting for the result. I mean I want to main thread to continue executing and no-wait for called method to get completed. I'm trying this snippet:

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

As you can see, I tried different ways; but non of them give me what I want. Do you have any idea, what would help me?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

Are you sure that's what you want to do? On ASP.NET, if you start up independent work like this (that is, work not related to an HTTP request), then that work may be aborted without your knowledge. In this scenario, your methods are called "log", so presumably they are logging asynchronously. So you only want to avoid the await if it's perfectly acceptable to occasionally lose logs. If you want your logs to be reliable, you'll need to keep the await. Your call.

Assuming that it's OK to occasionally lose logs, then you should at least register the work with the ASP.NET runtime. If you're on .NET 4.5.2, you can use HostingEnvironment.QueueBackgroundWorkItem, as such:

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

If you're on an older version of .NET (4.5 or 4.5.1), you can use my AspNetBackgroundTasks library:

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

The semantics between the two are slightly different (I have a writeup on my blog), but they both register the work with the ASP.NET runtime so at least it's not entirely unreliable like Task.Factory.StartNew or Task.Run is.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...