簡體   English   中英

如何讓代碼等待執行,直到另一個事件處理程序完成?

[英]How to let the code wait to be executed until the other event handler finished?

在下面的代碼中,我想使用geometryService (第三方提供的實用程序類)順序計算幾個形狀區域。 我失敗了,因為第二次時區計算必須等到第一次計算完成后才能進行。 要解決此問題,我可以將第二個區域計算放入完成計算事件處理程序中,但是代碼很混亂。 有沒有更好的方法可以讓geometryService.AreasAndLengthsAsync(secondShape)等待執行,直到geometryService.AreasAndLengthsAsync(firstShape)完成執行?

Shape firstShape = new Shape();
Shape secondShape = new Shape();

GeometryService geometryService = new GeometryService();
geometryService.AreaAndLengthsCompleted += GeometryService_AreasAndLengthsCompleted;
geometryService.AreasAndLengthsAsync(firstShape);
geometryService.AreasAndLengthsAsync(secondShape);

private void GeometryService_AreasAndLengthsCompleted(object sender, AreasAndLengthsEventArgs args){  }

您可以將每個Shape放入Queue<Shape>

然后開始第一個計算,並在完成的處理程序中檢查隊列中是否有其他任何Shape,如果有,請對其進行處理。

此外,您正在調用的方法是AreasAndLengthsAsync() 通過轉換,大多數API設計人員將包括名為AreasAndLengths()同步替代方案,而沒有Async部分。.因此,請尋找AreasAndLengths()作為替代方案。

這是異步方法的經典問題。 如果您使用的是新的MS Async CTP,則可以相當干凈地封裝其中的某些內容,但是如果您使用的是傳統內容,則很難從中獲得干凈的代碼。

我采用的方法之一是用連續傳遞模式包裝事件處理程序模式。 它不是很干凈,但是我更喜歡最終代碼的外觀。 因此,您可以執行以下操作:

public static void GetAreasAndLengthsAsync(Shape shape, Action<SomeResult> callback)
{
    var geometryService = new GeometryService();
    geometryService.AreasAndLengthsCompleted += (s, e) =>
    {
        if (callback != null)
        {
            callback(e.SomeResult);
        }
    };
    geometryService.AreasAndLengthsAsync(shape);
}

然后您可以像這樣使用它:

GetAreasAndLengthsAsync(firstShape, firstShapeResult =>
{
    GetAreasAndLengthsAsync(secondShape, secondShapeResult =>
    {
        DoSomethingWithTheseResults(firstShapeResult, secondShapeResult);
    });
});

無論如何,這樣的事情。 格式有點丑陋,但至少可以很好地表達您的意圖。 (尚未編譯代碼,可能有錯誤。)

如果您不想每次都重新創建geometryService,則可以在類的字段級別上執行此操作,然后將回調方法作為大多數Async方法包括的UserState參數的一部分傳遞。

您可以使用AutoResetEvent或ManualResetEvent,只需在類頂部定義一個,然后在要等待另一個事件的事件中調用Wait,然后在您等待的事件中調用Set,Wait將阻塞直到設置稱為。

http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx

我想補充一點,這不是理想的選擇,但是它必須具有序列化事件,並且您依賴第三方API而不是唯一的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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