[英]Using generic delegates to hook an async call
我有多個類似於以下內容的代碼:
void GetPerson(Action<PersonView, Exception> callback);
...
IsBusy = true;
_personRequested = true;
_service.GetPerson((person, error) =>
{
if (error != null)
{
return;
}
_person = person;
_personLoaded = true;
IsBusy = false;
});
我遇到的問題是,給定的類可能會觸發多個不同的異步調用,並且IsBusy屬性必須是“智能”的,不能僅因為調用“ A”已完成,而是“ B”和“ C”而無法關閉仍在等待中。 因此,_personRequested和_personLoaded布爾值。 但是,我想使用更通用的方法,但是不確定如何進行。
我最初的想法是建立一個函數,以上面的代碼作為委托,但是我一直對奇數語法感到困惑。 我想要的功能是,我只需要包裝整個內容並將其作為匿名方法傳遞給我的函數,然后在該函數和回調中處理類的繁忙狀態。
任何幫助表示贊賞,謝謝。
如果您要查找的只是某個正在使用中的指示符,則最好使用計數器而不是簡單的布爾標志。 然后,您可以使用Interlocked.Increment
和Interlocked.Decrement
以線程安全的方式修改該值。
在班級上聲明:
private volatile int isBusyCounter;
Interlocked.Increment(ref isBusyCounter);
_personRequested = true;
_service.GetPerson((person, error) =>
{
if (error != null)
{
return;
}
_person = person;
_personLoaded = true;
Interlocked.Decrement(ref isBusyCounter);
});
(由於需要在多個線程上修改值,因此需要使用“ Interlocked
,這可以確保更新不會彼此沖突;我們不在乎順序,因為最終會獲得相同的值是先發生還是先發生)
然后,不僅檢查IsBusy
,還檢查IsBusy > 0
。 變量需要是volatile
,這樣就不會對方法中的變量后續讀取進行優化(換句話說,如果您要在給定函數中循環或多次檢查此條件,則我們將volatile
放在該變量中以確保每次檢查該值,而不是在本地對其進行緩存)。
我可能會考慮將布爾值和關於它們的邏輯包裝到“狀態機”或類似的東西中: http : //www.codeproject.com/KB/architecture/statepatterncsharp.aspx
在每次開始和結束時都使用一個計數器並遞增,請確保使它運行安全
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.