控制台应用程序在执行回调之前退出

问题描述:

我有一个控制台应用程序,它执行类方法(在不同的项目中)。 该方法异步执行POST到web服务(这是一个3分钟的漫长操作),并具有返回受POST影响的记录数的回调。与此同时,程序继续执行其他需要不到3分钟的时间,程序在回调返回前退出。控制台应用程序在执行回调之前退出

在过去,我使用了下面描述的ManualResetEvent来防止完成,但在这种情况下,我的方法位于不同的类库中,我希望尽可能保持干净。


static ManualResetEvent resetEvent = new ManualResetEvent(false) 

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

void AsyncMethodCallback() 
{ 
    // Do processing on completion... 
    resetEvent.Set(); // Allow the program to exit 
} 

我会感谢任何帮助提出一个干净的模式来实现这一点,而不会污染被调用的类与执行标志。

如果可以(特别是,如果您使用的是.NET 4),请让您的CallAsyncMethod返回TaskTask<T>。然后你可以很容易地附加延续,等待它完成等。如果只有回调的目的是获得记录的数量,返回一个Task<int>将是理想的。您可以在异步方法中使用TaskCompletionSource<TResult>所以填充的结果真的很容易,所以你不需要回调在所有主类中,这将有一个主要的方法是这样的:

static void Main() 
{ 
    Task<int> asyncTask = CallAsyncMethod(); 
    // Do other things... 
    int count = asyncTask.Result; 
    // Do anything you need with the count 
} 

新的异步功能在C#5中可以很好地与Task<T>配合使用,所以当它到达时你将准备好迎接新版本。

+0

@Jon Skeet:确保[ContinueWith](http://msdn.microsoft.com/zh-cn/library/dd270696.aspx)被执行?我的意思是,如果调用线程将会死亡(在这种情况下是主线程),它是否会等待,因为还有一个“Task ”必须在完成时执行一个东西? – Tigran 2012-04-17 20:08:19

+0

@Tigran:在什么意义上?应用程序关闭之前?如果没有任何前台线程IIRC,则不需要。但在这里你不需要ContinueWith - 只需等待任务完成即可。 – 2012-04-17 20:10:32

+0

@Tigran:现在你已经编辑了评论:)不,如果Main方法返回并且没有其他前景线程,我不希望继续触发。但是阻止主要方法返回很容易 - 请参阅我的编辑。 – 2012-04-17 20:11:32

在另一个前台线程上启动webservice请求。在所有前景线程完成执行之前,应用程序不会退出。

new Thread(() => CallSynchronousMethod()).Start(); 
+0

好想法。没有想到前台线程块。 – Diego 2012-04-17 20:19:41