C# 如何在Main中调用异步方法?

C# 如何在Main中调用异步方法?,c#,asynchronous,async-await,task,C#,Asynchronous,Async Await,Task,但这似乎是一个死锁,屏幕上没有打印任何内容。您的Main方法可以简化。对于C#7.1及更新版本: class Program { static void Main(string[] args) { test t = new test(); t.Go().GetAwaiter().OnCompleted(() => { Console.WriteLine("finished"); });

但这似乎是一个死锁,屏幕上没有打印任何内容。

您的
Main
方法可以简化。对于C#7.1及更新版本:

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


}
对于C#的早期版本:


这是
async
关键字(以及相关功能)的一部分好处:回调的使用和混乱性质大大减少或消除了。

与其等待,不如使用
newtest().Go().GetAwaiter().GetResult()

因为这将避免异常被包装到AggregateExceptions中,所以您可以像往常一样用try-catch(Exception ex)块包围Go()方法。

只要您从返回的任务访问结果对象,就根本不需要使用GetWaiter(仅在您访问结果的情况下)

如果您有兴趣从sayHelloAsync获得结果并对其进行进一步处理:

sayHelloAsyn().GetAwaiter().OnCompleted(() => {
   Console.Write("done" );
});
Console.ReadLine();
等待函数的最后一种简单方法:

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();
自从C#v7.1
async
main
发布以来,可以使用这些方法,从而避免了在已经发布的答案中使用变通方法。已添加以下签名:

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

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

}
使用.Wait()

static void Main(字符串[]args){
SomeTaskManager SomeTaskManager=新建SomeTaskManager();
Task Task=Task.Run(()=>marginalentesgenerationtask.Execute());
task.Wait();
列表r=任务。结果;
} 
公共类任务管理器
{
公共异步任务执行(){
HttpClient=新的HttpClient();
client.BaseAddress=新Uri(“http://localhost:4000/");     
client.DefaultRequestHeaders.Accept.Clear();
HttpContent-HttpContent=newstringcontent(jsonevelope,Encoding.UTF8,“application/json”);
client.DefaultRequestHeaders.Accept.Add(新的MediaTypeWithQualityHeaderValue(“应用程序/json”);
HttpResponseMessage httpResponse=wait client.PostAsync(“,httpContent”);
if(httpResponse.Content!=null)
{
string responseContent=wait-httpResponse.Content.ReadAsStringAsync();
动态应答=JsonConvert.DeserializeObject(responseContent);
summaries=答案[0]。ToObject();
}
} 
}
尝试“结果”属性

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

class Program
{
    static void Main(string[] args)
    {
        test t = new test();
        t.Go().Result;
        Console.ReadKey();
    }
}
有关更多信息,请参阅:

顶级语句可能包含异步表达式。在这种情况下,合成的入口点返回一个
任务
,或
任务


似乎我发现了问题,cos GetAwaiter().OnCompleted()将立即返回主函数,因此当调用Console.Readkey()时,主线程正在阻塞,因此无法将任务返回的输出消息打印到屏幕上,因为它正在等待主线程解除阻塞。如果我用while(true){Thread.Sleep(1000);}替换Console.readkey(),效果很好。我无法重现您的死锁问题,但是,如果有人关心的话..尝试使用
Go().ConfigureAwait(false).GetAwaiter()
在异步方法中使用新上下文。在回答时,总是有一些关于为什么它是所问问题的“答案”的详细信息。我正在尝试使用
静态异步任务Main(string[]args)
,但我得到错误
CS5001程序不包含适合入口点的静态“Main”方法
。我已经检查了项目属性,下拉列表中没有可用的启动对象。使用最新更新的VS2017+.NET Core 2.0。我如何克服这个问题?@NightOwl888你能在项目属性中看到C#7.1吗?是的,我能,谢谢。默认设置为“最新主要版本”,因此默认为7.0。我改成了7.1,现在可以编译了。这需要更多关于选择和使用哪种方法的信息why@MarkAlicz不要对异步方法调用GetResult()。这将阻塞主线程。这不仅违背了异步方法的目的,而且为死锁留下了空间。@MarcGravel我已经将新方法纳入了我的答案中。戴维德的回答更加详细,但我不再过时。您可能需要修改项目文件以允许使用c#7.0及更高版本。此答案创建了一个后台线程,如果前台线程首先完成,则可能会导致问题
sayHelloAsyn().GetAwaiter().OnCompleted(() => {
   Console.Write("done" );
});
Console.ReadLine();
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();
static void main(string[] args){
  sayHelloAsync().Wait();
  Console.Read();
}

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

}
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();
    }
}
using System;
using System.Threading.Tasks;

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