我是使用async
修饰符进行异步编程的新手。我正在尝试弄清楚如何确保控制台应用程序的Main
方法实际上是异步运行的。
class Program
{
static void Main(string[] args)
{
Bootstrapper bs = new Bootstrapper();
var list = bs.GetList();
}
}
public class Bootstrapper {
public async Task<List<TvChannel>> GetList()
{
GetPrograms pro = new GetPrograms();
return await pro.DownloadTvChannels();
}
}
我知道这不是从“顶层”异步运行的。由于无法在Main
方法上指定async
修饰符,因此如何在main
中异步运行代码?
发布于 2014-07-07 08:26:48
你可以用这个简单的结构来解决这个问题:
class Program
{
static void Main(string[] args)
{
Task.Run(async () =>
{
// Do any async anything you need here without worry
}).GetAwaiter().GetResult();
}
}
这将把你所做的一切放在你想要的ThreadPool上(这样你开始/等待的其他任务就不会尝试重新加入它们不应该加入的线程),并等到所有事情都完成后再关闭控制台应用程序。不需要特殊的循环或外部库。
编辑:针对未捕获的异常合并Andrew的解决方案。
发布于 2013-07-11 03:34:54
您可以在不需要外部库的情况下执行此操作,还可以执行以下操作:
class Program
{
static void Main(string[] args)
{
Bootstrapper bs = new Bootstrapper();
var getListTask = bs.GetList(); // returns the Task<List<TvChannel>>
Task.WaitAll(getListTask); // block while the task completes
var list = getListTask.Result;
}
}
发布于 2014-09-03 04:54:33
我将添加一个所有其他答案都忽略的重要特性:取消。
第三方物流中最重要的事情之一是取消支持,而控制台应用程序有一个内置的取消方法(CTRL+C)。将它们绑定在一起非常简单。以下是我所有异步控制台应用程序的结构:
static void Main(string[] args)
{
CancellationTokenSource cts = new CancellationTokenSource();
System.Console.CancelKeyPress += (s, e) =>
{
e.Cancel = true;
cts.Cancel();
};
MainAsync(args, cts.Token).GetAwaiter.GetResult();
}
static async Task MainAsync(string[] args, CancellationToken token)
{
...
}
https://stackoverflow.com/questions/9208921
复制相似问题