我正在閱讀Stephen Cleary 的關于取消的博客文章,并且在以下代碼片段中看到了一些我以前從未見過的東西。
Constructor() => CancelButton.Enabled = false;
private CancellationTokenSource? _cts;
async void StartButton_Click(..)
{
StartButton.Enabled = false;
CancelButton.Enabled = true;
// Create a CTS for manual cancellation requests.
using var cts = _cts = new();
try
{
// Pass the token for that CTS to lower-level code.
await DoSomethingAsync(_cts.Token);
.. // Display success in UI.
}
catch (Exception ex)
{
.. // Display error in UI.
}
finally
{
StartButton.Enabled = true;
CancelButton.Enabled = false;
}
}
async void CancelButton_Click(..)
{
// Manually cancel the CTS.
_cts!.Cancel();
}
特別是using var cts = _cts = new();線路。
管理私有成員和區域變數的using處置嗎?
如果沒有在任何地方使用,為什么要分配區域變數?
這里發生了什么?
uj5u.com熱心網友回復:
這僅僅是因為你不能這樣做:
using _cts = new();
這將給出一個編譯錯誤,“預期識別符號”。
所以他引入了一個區域變數,該變數將在方法結束時處理:
using var cts = _cts = new();
現在它將編譯,cts并將被釋放(注意:它不會釋放_cts;它只會釋放引入的區域變數,cts)。
他想初始化一個欄位,_cts并在方法結束時自動處理創建的物件,這是一種簡單的方法。
這將是另一種寫法:
_cts = new();
using var cts = _cts;
另一種可能看起來不那么奇怪的撰寫方法是使用一個初始化_cts并回傳它的方法:
CancellationTokenSource initialiseCancellationToken()
{
var cts = new CancellationTokenSource();
_cts = cts;
return cts;
}
然后你會寫出不那么令人驚訝的:
using var cts = initialiseCancellationToken();
你付出你的錢,你做出你的選擇!
注意:您可能很想這樣寫:
CancellationTokenSource initialiseCancellationToken()
{
_cts = new CancellationTokenSource();
return _cts;
}
但這有一個微妙的競爭條件!你能發現它嗎(假設它initialiseCancellationToken()可以被多個執行緒同時呼叫)?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/497327.html
