How can I call an async method in Main?

public class test
{
public async Task Go()
{
await PrintAnswerToLife();
Console.WriteLine("done");
}


public async Task PrintAnswerToLife()
{
int answer = await GetAnswerToLife();
Console.WriteLine(answer);
}


public async Task<int> GetAnswerToLife()
{
await Task.Delay(5000);
int answer = 21 * 2;
return answer;
}
}

if I want to call Go in main() method, how can I do that? I am trying out c# new features, I know i can hook the async method to a event and by triggering that event, async method can be called.

But what if I want to call it directly in main method? How can i do that?

I did something like

class Program
{
static void Main(string[] args)
{
test t = new test();
t.Go().GetAwaiter().OnCompleted(() =>
{
Console.WriteLine("finished");
});
Console.ReadKey();
}




}

But seems it's a dead lock and nothing is printed on the screen.

94969 次浏览

你的 Main方法可以被简化,对于 C # 7.1和更新的:

static async Task Main(string[] args)
{
test t = new test();
await t.Go();
Console.WriteLine("finished");
Console.ReadKey();
}

对于 C # 的早期版本:

static void Main(string[] args)
{
test t = new test();
t.Go().Wait();
Console.WriteLine("finished");
Console.ReadKey();
}

这是 async关键字(和相关功能)的美妙之处的一部分: 回调的使用和令人困惑的特性大大减少或消除了。

与其等,不如用 new test().Go().GetAwaiter().GetResult() since this will avoid exceptions being wrapped into AggregateExceptions, so you can just surround your Go() method with a try catch(Exception ex) block as usual.

As long as you are accessing the result object from the returned task, there is no need to use GetAwaiter at all (Only in case you are accessing the result).

static async Task<String> sayHelloAsync(){


await Task.Delay(1000);
return "hello world";


}


static void main(string[] args){


var data = sayHelloAsync();
//implicitly waits for the result and makes synchronous call.
//no need for Console.ReadKey()
Console.Write(data.Result);
//synchronous call .. same as previous one
Console.Write(sayHelloAsync().GetAwaiter().GetResult());


}

如果您希望等待任务完成并做一些进一步的处理:

sayHelloAsyn().GetAwaiter().OnCompleted(() => {
Console.Write("done" );
});
Console.ReadLine();

如果你对 SayHelloAsync 的结果感兴趣并对其进行进一步处理:

sayHelloAsync().ContinueWith(prev => {
//prev.Result should have "hello world"
Console.Write("done do further processing here .. here is the result from sayHelloAsync" + prev.Result);
});
Console.ReadLine();

One last simple way to wait for function:

static void main(string[] args){
sayHelloAsync().Wait();
Console.Read();
}


static async Task sayHelloAsync(){
await Task.Delay(1000);
Console.Write( "hello world");


}

自从 C # v7.1 async发布以来,main方法已经可以使用,从而避免了在已经发布的答案中使用变通方法。增加了以下签名:

public static Task Main();
public static Task<int> Main();
public static Task Main(string[] args);
public static Task<int> Main(string[] args);

这允许您像下面这样编写代码:

static async Task Main(string[] args)
{
await DoSomethingAsync();
}


static async Task DoSomethingAsync()
{
//...
}
class Program
{
static void Main(string[] args)
{
test t = new test();
Task.Run(async () => await t.Go());
}
}
public static void Main(string[] args)
{
var t = new test();
Task.Run(async () => { await t.Go();}).Wait();
}

使用。等待()

static void Main(string[] args){
SomeTaskManager someTaskManager  = new SomeTaskManager();
Task<List<String>> task = Task.Run(() => marginaleNotesGenerationTask.Execute());
task.Wait();
List<String> r = task.Result;
}


public class SomeTaskManager
{
public async Task<List<String>> Execute() {
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:4000/");
client.DefaultRequestHeaders.Accept.Clear();
HttpContent httpContent = new StringContent(jsonEnvellope, Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage httpResponse = await client.PostAsync("", httpContent);
if (httpResponse.Content != null)
{
string responseContent = await httpResponse.Content.ReadAsStringAsync();
dynamic answer = JsonConvert.DeserializeObject(responseContent);
summaries = answer[0].ToObject<List<String>>();
}
}
}

试试“结果”属性

class Program
{
static void Main(string[] args)
{
test t = new test();
t.Go().Result;
Console.ReadKey();
}
}

C # 9顶级语句 更加简化了事情,现在你甚至不需要做任何额外的事情来从你的 Main调用 async方法,你可以这样做:

using System;
using System.Threading.Tasks;


await Task.Delay(1000);
Console.WriteLine("Hello World!");

更多信息见 C # 9.0中的新特性: 顶级语句:

顶级语句可能包含异步表达式。在这种情况下,合成的入口点返回 TaskTask<int>