簡體   English   中英

使用通用委托掛接異步調用

[英]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.IncrementInterlocked.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM