3 回答

TA貢獻1862條經驗 獲得超6個贊
考慮以下兩條路徑:
textBox1.Text += await task;
對比
string newText = await task;
textBox1.Text += newText;
在第一個示例中,textBox1.Text 的當前值首先被所有三次單擊立即讀取,這可能只是原始的空文本框值。然后,當每個完成時,它會寫入原始值(就像讀取時一樣,提醒仍然是空字符串)加上您要連接的“1”。所以如果你快速點擊按鈕,三個線程都會寫入“”+“1”的值
在第二個示例中,您等待獲取要連接的結果文本,然后(在 UI 線程上)執行 += 操作,該操作將不間斷地讀取、連接和寫入。
如果您在 += 中等待,則在開始等待之前讀取原始值,并將結果連接應用于保存在等待上下文中的值。
現在這有意義嗎?

TA貢獻1827條經驗 獲得超8個贊
某些語言(例如 C++)允許編譯器選擇在給定語句中計算的順序表達式。但是 C# 消除了這種歧義:評估總是從左到右。
textBox1.Text += await task;
在 C# 中,沒有特殊的 += 運算符,它只是擴展為:
textBox1.Text = textBox1.Text + await task;
現在,如果我們從左到右評估,它應該評估的第一件事是 textBox1.set_Text 用于賦值。如果您要在右側執行一些會更改 textBox1 的值的操作,您最終仍會分配給原始 textBox1,而不是新值。
接下來要評估的是 textBox1.get_Text。這應該返回您的“”值。
然后它評估“等待任務”。此時,它陷入等待,無法繼續評估語句,因此它將當前堆棧幀的重要內容轉儲到堆對象中以備后用。當它回來繼續評估時,我們現在評估了以下信息:
我們要寫入的對象的地址。
字符串值“”。
字符串值“1”。
剩下要做的就是將捕獲的“”添加到等待的“1”,并將其分配給捕獲的 textBox1。
如果您快速連續多次執行此操作,則所有 3 個輸入每次都將相同。換句話說,它的行為與標準所描述的完全一致。人們給出的建議將其放在上一行,如下所示:
var temp = await task; textBox1.Text += temp;
這只是將等待移到 textBox1.Text 之前。您實際上可以進行重新排序內聯并給出預期的結果,只需顛倒語句中表達式的順序即可:
textBox1.Text = string.Concat( new[] { await task, textBox1.Text }.Reverse());

TA貢獻1856條經驗 獲得超11個贊
這里沒有編譯器錯誤。但是,這條線是你的問題
textBox1.Text += await task;
如果您更改以下內容,您會發現一致的結果。
var result = await task; textBox1.Text += result;
一個簡單的類比是您向某人詢問結果(例如單詞或數字),當您完成自己的工作后,您希望將結果添加到他們的結果中。當您非??斓囟啻螆绦写瞬僮鲿r,就會出現問題。你得到了他們原來的價值 3 次(你說,給我你所擁有的,給我你所擁有的,給我你所擁有的),你要去做你的 3 個獨立的工作,當你回來時你只需添加它到原始值(未修改的值),這似乎有效地覆蓋了該值并且不起作用。
- 3 回答
- 0 關注
- 163 瀏覽
添加回答
舉報