有一個回傳 a 的庫ValueTask,我有一個正在使用 ValueTask 的同步方法。問題是有以下警告:
CA2012:除非實體已經完成,否則不應直接訪問 ValueTask 實體的結果。與任務不同,在操作完成之前,不能保證在 ValueTask 上呼叫 Result 或 GetAwaiter().GetResult()。如果您不能簡單地等待該實體,請考慮首先檢查其 IsCompleted 屬性(或者,如果您知道是這種情況,則斷言它是真的)。
我如何解決它?
public void CreateListenKey()
{
var result = CreateSpotListenKeyAsync().GetAwaiter().GetResult(); // CA2012: ValueTask instances should not have their result directly accessed unless the instance has already completed. Unlike Tasks, calling Result or GetAwaiter().GetResult() on a ValueTask is not guaranteed to block until the operation completes. If you can't simply await the instance, consider first checking its IsCompleted property (or asserting it's true if you know that to be the case).
if (result.Success)
{
using var document = JsonDocument.Parse(result.Data!);
lock (_listenKeyLocker)
{
if (document.RootElement.TryGetProperty("listenKey", out var listenKeyElement))
{
var listenKey = listenKeyElement.GetString();
ListenKey = listenKey;
}
}
}
}
// library
public async ValueTask<CallResult<string>> CreateSpotListenKeyAsync()
{
var result = await SendPublicAsync<string>(
"/api/v3/userDataStream",
Method.Post);
return result;
}
// Can't just make it async, because these listen key methods are used in an event handler.
private void OnKeepAliveTimerElapsed(object? sender, ElapsedEventArgs e)
{
RestApi.PingListenKey();
}
uj5u.com熱心網友回復:
同步等待 a 完成的推薦方法ValueTask是將其轉換為 a Task,AsTask方法如下:
Task<CallResult<string>> task = CreateSpotListenKeyAsync().AsTask();
var result = task.GetAwaiter().GetResult();
if (result.Success)
{
//...
在您的情況下,根據CreateSpotListenKeyAsync方法的實作,這種轉換很可能會產生零開銷。假設ValueTask<CallResult<string>>在創建時尚未完成,很可能它在內部包裝了 a Task<CallResult<string>>,因此轉換將只回傳包裝后的任務。它似乎不太可能包裝IValueTaskSource<T>介面的實作,在這種情況下,轉換會產生分配一些輕量級物件的成本。
如果您預計ValueTask<CallResult<string>>創建時會經常完成,您可以像這樣優化您的代碼:
var valueTask = CreateSpotListenKeyAsync();
CallResult<string> result;
if (valueTask.IsCompletedSuccessfully)
{
result = valueTask.Result;
}
else
{
result = valueTask.AsTask().GetAwaiter().GetResult();
}
也可以優化IValueTaskSource<T>基于值任務的同步等待,但這不是微不足道的,而且預期的好處是如此微不足道,以至于不太可能值得付出努力。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/495281.html
下一篇:在列印預覽的列中添加二維碼
