为什么委托需要在方法触发之前调用EndInvoke?如果我需要调用EndInvoke(它阻塞线程)那么它真的不是异步调用吗?
这是我试图运行的代码.
class Program
{
private delegate void GenerateXmlDelegate();
static void Main(string[] args)
{
GenerateXmlDelegate worker = new GenerateXmlDelegate(GenerateMainXml);
IAsyncResult result = worker.BeginInvoke(null, null);
}
private static void GenerateMainXml()
{
Thread.Sleep(10000);
Console.WriteLine("GenerateMainXml Called by delegate");
}
}
Run Code Online (Sandbox Code Playgroud)
SLa*_*aks 16
你需要调用的原因EndInvoke是为了避免内存泄漏; .Net将存储有关函数结果(或异常)的信息,直到您调用为止EndInvoke.
您可以调用EndInvoke您提供的完成处理程序BeginInvoke并保留异步性质.
编辑:
例如:
class Program {
private delegate void GenerateXmlDelegate();
static void Main(string[] args) {
GenerateXmlDelegate worker = new GenerateXmlDelegate(GenerateMainXml);
IAsyncResult result = worker.BeginInvoke(delegate {
try {
worker.EndInvoke();
} catch(...) { ... }
}, null);
}
private static void GenerateMainXml() {
Thread.Sleep(10000);
Console.WriteLine("GenerateMainXml Called by delegate");
}
}
Run Code Online (Sandbox Code Playgroud)
如果要激活异步调用并忘记它,可以使用ThreadPool,如下所示:
ThreadPool.QueueUserWorkItem(delegate { GenerateMainXml(); });
Run Code Online (Sandbox Code Playgroud)
正如SLaks所说,EndInvoke可以防止内存泄漏.
BeginInvoke仍然是异步的; 考虑以下代码:
static void Main() {
Func<double> slowCalculator = new Func<double>(PerformSlowCalculation);
IAsyncResult slowCalculation = slowCalculator.BeginInvoke(null, null);
// lots of stuff to do while slowCalculator is doing its thing
Console.WriteLine("Result is {0}", slowCalculator.EndInvoke(slowCalculation));
}
static double PerformSlowCalculation() {
double result;
// lots and lots of code
return result;
}
Run Code Online (Sandbox Code Playgroud)
如果这段代码是在没有BeginInvoke/ EndInvokecalls的情况下编写的,则PerformSlowCalculation必须先完成Main才能完成其余的"很多东西"; 这样,两者可以同时发生.
现在,在你使用a的例子中GenerateXmlDelegate,EndInvoke即使你没有返回任何东西,你仍然需要.这样做的方法是:
static void Main(string[] args) {
GenerateXmlDelegate worker = new GenerateXmlDelegate(GenerateMainXml);
IAsyncResult result = worker.BeginInvoke(GenerateXmlComplete, null);
}
private static void GenerateXmlComplete(IAsyncResult result) {
AsyncResult realResult = result as AsyncResult;
GenerateXmlDelegate worker = result.AsyncDelegate as GenerateXmlDelegate;
worker.EndInvoke();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7378 次 |
| 最近记录: |