我正在尝试编写一个非常简单的异步代码。我有一个void方法,它不接受任何参数,这些参数是从Windows服务调用的。我想把它打开异步,这样服务就不必等待方法完成了。
我创建了一个非常简单的测试应用程序,以确保我正确编码,但异步方法没有被调用。任何人都能看到我做错了什么?我顺便使用.NET 4.0,所以我不能使用await(这会更简单!)。
这是我的整个测试样本......
using System;
using System.Threading;
namespace AsyncCallback {
internal class Program {
private static void Main(string[] args) {
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - About to ask for stuff to be done");
new Action(DoStuff).BeginInvoke(ar => StuffDone(), null);
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Asked for stuff to be done");
}
private static void StuffDone() {
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Stuff done");
}
private static void DoStuff() {
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Starting to do stuff");
Thread.Sleep(1000);
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Ending doing stuff");
}
}
}
感谢您提供任何帮助。
答案 0 :(得分:6)
在ThreadPool
中部署异步方法之前,您的程序正在终止。保持你的程序开放一点。可能Console.ReadKey()
结束时Main
?
答案 1 :(得分:5)
任何应用程序都会在没有完成执行的前景线程时立即结束。如果有任何后台线程,他们将不会保持进程“活着”。
因为您在后台启动异步任务,并且没有任何东西使前台线程保持运行,所以整个过程都在退出。
您需要在前台线程中运行异步任务(据我所知,这不能用BeginInvoke
完成,您需要显式创建新的Thread
)或者做其他事情来阻止主线程直到完成。
答案 2 :(得分:1)
你不是在等待完成,所以试试这样的事情
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - About to ask for stuff to be done");
var a = new Action(DoStuff);
var iar = a.BeginInvoke(ar => StuffDone(), null);
a.EndInvoke(iar);
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Asked for stuff to be done");
答案 3 :(得分:1)
首先,您的回调不是正确的委托......应该是
public delegate void AsyncCallback(IAsyncResult ar);
你的是
private static void StuffDone()
只需将其更改为:
private static void StuffDone(IAsyncResult ar){}
然后在你的回调中确保通过调用
实际执行ActionEndInvoke
<{1}} 上的
像这样:
AsyncState
您需要做的另一个更改是,当您在main函数中实例化Action时,将操作本身作为private static void StuffDone(IAsyncResult ar)
{
Action r = ar.AsyncState as Action;
r.EndInvoke(ar);
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Stuff done");
}
方法的'object'参数传递,如下所示:
BeginInvoke
这应该解决你的问题:)