![](/img/trans.png)
[英]why we need EndInvoke() to return value of asynchronous call in delegate?
[英]Why does asynchronous delegate method require calling EndInvoke?
為什么委托需要在方法觸發之前調用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");
}
}
你需要調用EndInvoke
的原因是為了避免內存泄漏; 在您調用EndInvoke
之前,.Net將存儲有關函數結果(或異常)的信息。
您可以在為BeginInvoke
提供的完成處理程序中調用EndInvoke
,並保留異步性質。
編輯 :
例如:
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");
}
}
如果要激活異步調用並忘記它,可以使用ThreadPool ,如下所示:
ThreadPool.QueueUserWorkItem(delegate { GenerateMainXml(); });
正如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;
}
如果這段代碼是在沒有BeginInvoke
/ EndInvoke
調用的情況下編寫的,那么在Main
可以完成剩余的“很多東西”之前,必須完成PerformSlowCalculation
。 這樣,兩者可以同時發生。
現在,在使用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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.