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.1async
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!");