簡體   English   中英

從異步任務在主線程上調用委托

[英]Call delegate on main thread from asynchronous task

這似乎很簡單...想要在.NET 3.5(如果可能,則兼容CF)中執行此操作。

我想調用一個函數,並將其傳遞給回調函數,該函數將在完成時觸發。 怎么做?

示例代碼:

public static void downloadTemplateDataAsync(int officeID, int? workbookID, TemplateType templateType, int? templateID, TemplateRequestDelegate callback)
{
    Template t = null;
    System.Threading.Thread callingThread = System.Threading.Thread.CurrentThread;
    new System.Threading.Thread(() =>
    {
        t = downloadTemplateData(officeID, workbookID, templateType, templateID);

        // Dispatch callback
        callback.Invoke(t);
    }).Start();
 }

我同意注釋中的問題,為什么要在主線程上執行委托? 就是說,如果您堅持可以用兩種方法完成這兩種方法,那么這兩種方法都需要您為主線程實現某種基礎結構以允許它。

最簡單的理解是編寫一些明確的代碼來進行協調。 例如,使用原始代碼:

public static void downloadTemplateDataAsync(int officeID, int? workbookID, TemplateType templateType, int? templateID, TemplateRequestDelegate callback)
{
    Template t = null;
    object o = new object();
    System.Threading.Thread callingThread = System.Threading.Thread.CurrentThread;
    new System.Threading.Thread(() =>
    {
        t = downloadTemplateData(officeID, workbookID, templateType, templateID);

        // Signal completion
        lock (o) Monitor.Pulse(o);
    }).Start();

    lock (o) Monitor.Wait(o);
    callback.Invoke(t);
    }
 }

請注意,這將阻塞您的主線程,而另一個線程則起作用。 這幾乎總是錯誤的做法,但是確實可以完成您的請求。

如果希望主線程繼續執行其他操作,則需要將其實現為執行其他操作,同時還定期檢查任務是否完成,這時它將調用委托。 WinForms和WPF程序具有一個消息泵送循環,該循環也用於此目的。 如果要在非GUI程序中實現相同的行為,則必須重新發明該特定的輪子。

從好的方面來說,如果您這樣做並且同時實現了一個可與您的實現一起使用的自定義SynchronizationContext,那么您基本上可以免費獲得.NET的其他跨線程功能。 在不那么光明的一面,盡一切是大量的工作。

您真的確定您需要這種行為嗎? 如果您更詳細地說明您實際要完成的工作,則可能會得到更好的答案。

暫無
暫無

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

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