我想分享一些在設定該背景關系資料的執行緒/任務的整個生命周期中保留的背景關系資料。
查看下面的偽代碼,我有多個任務都呼叫異步方法。不管怎樣,它們都是“主”、父、任務的子任務。
task1 將設定可供該任務的所有子級使用的背景關系資料,而 task2 將執行相同的操作,但其所有子級都可以訪問其資料。
tasks (add) task1
Set context data (value = "1")
(await) --> task1-B (await) --> task1-C (await) --> thread1-D --|
|------------------------------------------------------------------|
UnSet context data (value = null)
tasks (add) task2
Set context data (value = "2")
(await) --> task2-B (await) --> task2-C (await) --> thread2-D --|
|------------------------------------------------------------------|
UnSet context data (value = null)
await tasks.WaitAll();
我能做的是將值從方法傳遞到方法,始終確保傳遞“背景關系”。
這種方法的問題在于它意味著重寫所有子方法(在我的示例中為方法 B、C、D)。
另一個問題是某些方法被其他方法呼叫,例如方法E可以呼叫方法C
task2-E (await) --> task2-C (await) --|
|--------------------------------------|
在上述情況下,可能已經設定了背景關系(以某種方式重新進入),或者根本沒有設定。
我知道“子”任務無法獲得其父任務或父任務無法獲得其子任務,否則我可以設定一些全域串列,以某種方式跟蹤所有背景關系。
我只是想知道是否有可能有一個獨特的“背景關系”作為任務和子任務。
uj5u.com熱心網友回復:
你正在尋找AsyncLocal<T>. AsyncLocal<T>我的博客中的一些
警告:
- 它應該在一個
async方法中設定,因為這會觸發邏輯執行緒背景關系的“寫入時復制”行為。 - 您應該只存盤不可變資料。
通常,我使用的代碼最終看起來像這樣:
internal static class MyAsyncContext
{
// string is immutable
private static AsyncLocal<string> _asyncLocal = new();
// this should ONLY be called from an async method
public IDisposable Set(string value)
{
var previous = _asyncLocal.Value;
_asyncLocal.Value = value;
return Disposable.Create(() => _asyncLocal.Value = previous);
}
public string? TryGet() => _asyncLocal.Value;
}
(這是使用我的Disposables 庫Disposable中的助手)
父方法中的用法:
async Task task1()
{
using var context = MyAsyncContext.Set("1");
await task1B();
}
子方法中的用法:
async Task task1D()
{
var contextData = MyAsyncContext.TryGet();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/411875.html
標籤:
上一篇:渲染組件后API呼叫回傳影像
下一篇:異步加載React組件
