簡體   English   中英

為什么異步委托方法需要調用EndInvoke?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM