簡體   English   中英

從異步列表中刪除項目 function

[英]Removing items from list in an async function

我正在編寫 function 以通過在列表中保留訂閱 ID 列表來刪除所有訂閱。

我遇到了問題

     foreach (var subscriptionId in _listOfSubscriptionIds)
     {
           await _hubProxy.Invoke("removeSubscription", subscriptionId);
           _listOfSubscriptionIds.Remove(subscriptionId);
     }

因為在 foreach 循環中修改列表會引發錯誤。 我在這個社區發現我可以做foreach(var subscriptions in _listOfSubscriptionIds.ToList())但這在空間復雜度方面聽起來很糟糕,特別是如果有大約 10000000 個訂閱。

所以我將其更改為以下內容:

    public async Task RemoveSubscription (string subscriptionId)
    {
        await _hubProxy.Invoke("removeSubscription", subscriptionId);
        _listOfSubscriptionIds.Remove(subscriptionId);
    }
    public void RemoveAllSubscriptions()
    {
        _listOfSubscriptionIds.ForEach(async subscriptionId => await RemoveSubscription(subscriptionId));
    }

一些問題:

  1. 我認為第二個在空間和時間復雜度方面更好,但我是對的嗎?

  2. 在第二種情況下,我可能會丟失一個可能的競爭條件嗎?

  3. 在 RemoveSubscription 中,是否也等待_listOfSubscriptionIds.Remove(subscriptionId)因為它處於異步 function...?

編輯:我沒有分享的一個細節使得調用_listOfSubscriptionIds.Clear()或迭代_listOfSubscriptionIds有問題的是_hubProxy上可能有多個客戶端,每個客戶端都有其獨特的訂閱集。

具有訂閱 ID {a, b, c, d, e} 的客戶端 1

具有子 ID {f, g, h, I, j, k} 的客戶端 2

具有子 ID、{l、m、n、o、p} 等的客戶端 3。

這意味着當我調用 client1.RemoveAllSubscriptions() 時,它也可能會清除 client2、client3 等的訂閱 ID。

您的ForEach本質上是一勞永逸的; 它不能確保所有任務都運行完成。

您最好反向使用 for 循環,並保留任務以便等待它們:

var tasks = new List<Task>();
for (int i = _listOfSubscriptionIds.Count - 1; i >= 0; i--)
{
    tasks.Add(RemoveSubscription(_listOfSubscriptionIds[i]));
}

await Task.WhenAll(tasks);

反向迭代確保特定索引處的值在循環期間不會改變。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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