39

我目前正在编写一个 C# 控制台应用程序,它生成许多指向网站上不同图像的 URL,然后使用WebClient.DownloadDataAsync().

我的问题是,一旦进行了第一次异步调用,控制台应用程序就会认为程序已完成并在异步调用返回之前终止。通过使用,Console.Read()我可以强制控制台保持打开状态,但这似乎不是很好的设计。此外,如果用户在此过程中(在控制台等待输入时)按 Enter 键,程序将终止。

在我等待异步调用返回时,是否有更好的方法来防止控制台关闭?

编辑:调用是异步的,因为我在下载时通过控制台向用户提供状态指示器。

4

4 回答 4

52

是的。使用ManualResetEvent,并进行异步回调调用event.Set()。如果 Main 例程阻塞event.WaitOne(),则在异步代码完成之前它不会退出。

基本的伪代码如下所示:

static ManualResetEvent resetEvent = new ManualResetEvent(false);

static void Main()
{
     CallAsyncMethod();
     resetEvent.WaitOne(); // Blocks until "set"
}

void DownloadDataCallback()
{
     // Do your processing on completion...

     resetEvent.Set(); // Allow the program to exit
}
于 2010-10-01T15:48:51.447 回答
28

另一种选择是调用异步 Main 方法并等待返回的任务。

static void Main(string[] args)
{
    MainAsync(args).Wait();
}

static async Task MainAsync(string[] args)
{
    // .. code goes here
}

从 .NET 4.5 开始,您现在可以调用GetAwaiter().GetResult()

static void Main(string[] args)
{
    MainAsync(args).GetAwaiter().GetResult();
}

.Wait() 与 .GetAwaiter().GetResult() 有什么区别?

于 2013-01-29T03:10:36.700 回答
6

如果这就是您的应用程序正在做的所有事情,我建议您省略异步调用;您特别希望应用程序“挂起”直到下载完成,因此使用异步操作与您在这里想要的相反,尤其是在控制台应用程序中。

于 2010-10-01T15:49:32.460 回答
1

需要说明的是,在 C# 7.1Main中现在可以标记为async.

static async Task Main()
{
  await LongRunningOperation();
}
于 2018-06-11T15:08:13.563 回答