2015-09-25 25 views
2

我有不同的情況,比在this question,因此另一個問題。InvokeAsync命令

讓我們下面的例子:

void PerformanceCriticalMethod() 
{ 
    Dispatcher.Invoke(() => Log.Add("1")); 
    ... some job 
    Dispatcher.Invoke(() => Log.Add("2")); 
} 

Invoke產生的性能問題。在試圖解決它,我代替Invoke使用InvokeAsync似乎工作,但什麼2將輸出1後是很重要的。

我可以依靠假設如果兩個InvokeAsync從同一個線程調用,他們將按相同的順序執行?我的winapi的螺母告訴我這是真的,但我想確定。

而作爲連接彼此相關的問題是一樣的:如果同樣的方法是通過InvokeAsync行動從不同的線程調用,多麼好機會,有它第一次執行線程誰早叫InvokeAsync

P.S .:我有感覺問題應該改寫爲「InvokeAsync的工作方式」,但「訂單」這個詞可能是人們(包括我)嘗試搜索的100%候選人。

回答

1

請檢查了這一點http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/Threading/Dispatcher.cs,1045

當你調用InvokeAsync,操作被投入PriorityQueue的,所以我想如果您調用具有相同優先級的多個操作,則可以確信這些操作將以相同的順序執行。

+0

這個答案非常接近我想知道的。好吧,它使用'PriorityQueue',所以它**必須**以相同的順序(至少我的希望現在有確認)。但我在那裏看到一個「鎖」,它有什麼作用? – Sinatr

+0

看起來像是在多線程的情況下,由於這個鎖,它將以相同的順序執行。 – olegk

1

Dispatcher.InvokeAsync()返回一個DispatcherOperation對象。它有一個屬性Task

獲取表示當前操作的T:System.Threading.Task。

您可以使用Task支持的所有操作。例如繼續進行第二次調度員調用。

Dispatcher.InvokeAsync(() => Log.Add("1")).Task.ContinueWith(() => { 
    Dispatcher.InvokeAsync(() => Log.Add("2")); 
}); 

由於尤瓦Itzchakov說,如果你只是想爲了執行它們,你可以awaitInvokeAsync通話,因爲DispatcherOperationawaitable(因爲它暴露了一個GetAwaiter方法)。

我可以依靠假設如果兩個InvokeAsync從相同的線程調用,他們將按相同的順序執行?

我絕不會依賴基礎系統上的假設。它使系統變得脆弱(你永遠不知道這個假設是否仍然)。

+0

我不想等待'InvokeAsync'。這甚至是可能的:1)不等待2)確保按照「InvokeAsync」的順序? – Sinatr

+0

如果你想明確確保'2'在'1'之後被執行並且不想使用await,你必須使用延續('Task.ContinueWith')。我沒有看到任何其他選項。 – Domysee

0

Dispatcher.InvokeAsync返回一個DispatcherOperation,這是一個可等待的(它暴露了GetAwaiter方法)。如果你想保證執行順序,你可以await他們所需的順序:

async Task PerformanceCriticalMethodAsync() 
{ 
    await Dispatcher.InvokeAsync(() => Log.Add("1")); 
    ... some job 
    await Dispatcher.InvokeAsync(() => Log.Add("2")); 
} 
+0

'await Dispatcher.InvokeAsync'基本上很簡單'Invoke'(代價高昂),我想避免浪費時間去做「一些工作」,只能保證按照正確的順序。我可以等待下一次執行之前首先調用,但問題是我將會有多少**調用**(給出的例子被簡化了),所以'await'對我來說是不好的,因爲它會消耗等待任務完成所需的時間。我不想等。 – Sinatr

+0

@Sinatr你不會與'await'同步阻塞。當線程本身被釋放時,控制權返回給調用者。與此同時,您可以自由地執行更多的工作。 –

+0

沒有來電者。 「一些工作」部分應該在調用方法後立即運行,並且關鍵不要使用「調用」來延遲它。我可以使用'queue'和producer/consumer,但是我的希望是'InvokeAsync'已經做到了。請參閱@olegk答案。 – Sinatr

0

我已經作出了結論,我自己:

誰打電話InvokeAsync首先會得到其動作先得到服務。

它無關,與正常async方法不確定性「誰將會先運行」,因爲執行的InvokeAsync是一個純粹的線程安全的生產者/消費者隊列(可在sources可以看出,由於@olegk答案) 。