簡體   English   中英

為什么此鎖語句不起作用

[英]Why this lock statement does not work

所以我有這個相當簡單的代碼。 看一看。

var monitor = new object();

var result = 0;

Task.Factory.StartNew(() =>
{
    var childTaskFactory = new TaskFactory(TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously);
    for (int i = 0; i < 5; i++)
    {
        childTaskFactory
            .StartNew<int>(() => CreateRequest()) // this methods just return the integer value 10
            .ContinueWith(task => { lock (monitor) { result += task.Result; } });
    }
}).Wait();

基本上,我實例化了一個用於獲取鎖的新對象。 然后我將創建一個設置為0的int變量。之后,我將創建一個父Task ,其中將包含5個子Task ,所有這些子任務都調用一個名為CreateRequest的方法,該方法只會返回數字10(不要介意方法的名稱)。 每個子Task都有一個延續,該延續獲得了monitor鎖定,並且僅將CreateRequest方法返回的數字10添加到result變量中。 在程序結束時,我希望變量result包含值50。但事實並非如此。 我的意思是有時這樣做,但有時將其設置為20、30或40。顯然我誤解了如何使用lock語句,或者實現存在問題。 我很可能在代碼中有一些錯誤。 此代碼在Program類的static Main方法內部。

因為當其他所有任務都開始時,您的主要任務已完成。 它不會等到他們全部完成 因此,有時您會在所有子任務運行之前捕獲result的價值。

作為測試,將Thread.Sleep(1000)放在Wait() ,您將看到result按預期更新。 但是不要將其用於生產代碼。 而是編寫等待所有子任務完成的代碼。

如果我正確理解代碼,則實際上並沒有等待所有5個任務完成。 相反,它等待所有5個任務開始,在此期間,顯然一個或多個任務可能完成,從而為您提供10、20、30或40,而不是50。

這是一個等待多個任務完成的示例 您將需要WaitAll版本,而不是WaitAny

您還可以通過將子任務添加到列表中,然后在末尾添加斷點來檢查正在發生的情況。 如果然后在“本地”窗口中檢查對象,則會看到某些任務的狀態仍為“正在運行”。

請注意,將任務添加到列表中可能會影響執行,並導致結果更頻繁地等於50。

暫無
暫無

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

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