我有一個多線程問題。退出循環,如果另一個線程輸入在
我有一個方法被調用來刷新幾個項目。
在這種方法中,我遍歷項目列表並刷新它的一個屬性。
該列表有很多元素,我們必須做一些數學計算它的屬性。
此操作的當前的代碼如下所示:
public void AddItemsWithLayoutRefresh(IEnumerable<MyItem> items){
_control.Invoke(()=>{
AddItems(items);
for(int i =0;i<_guiItems.Count;i++){
//The goal is to have a condition here to "break" the loop and let the next call to RefreshLayout proceed
_guiItems[i].Propriety = ComputePropriety(_guiItems[i]);
}
});
}
的問題是,我可以有4個電話,這是目前剛剛上阻塞Invoke
。 我必須完成「AddItems」方法,但是關於「for」循環中的所有內容,如果我知道它將在後面執行,我可以放棄這個,不會有任何問題。
但如何以線程安全的方式做到這一點?
如果我把private bool _isNewRefreshHere;
設置爲真,然後再輸入調用,然後檢查Invoke
,我不保證沒有兩個調用已經達到Invoke BEFORE我在for循環中檢查它。
那麼我怎樣才能當我在我的循環,當一個新的電話是我的方法?
解決方案 基於安德烈Mohar的答案,我做了以下內容:
private long m_refreshQueryCount;
public void AddItemsWithLayoutRefresh(IEnumerable<MyItem> items){
Interlocked.Increment(ref m_refreshQueryCount);
_control.Invoke(()=>{
Interlocked.Decrement(ref m_refreshQueryCount);
AddItems(items);
for(int i =0;i<_guiItems.Count;i++){
if (Interlocked.Read(ref m_refreshQueryCount) > 0)
{
break;
}
_guiItems[i].Propriety = ComputePropriety(_guiItems[i]);
}
});
}
這似乎是非常漂亮的工作
你爲什麼不使用'lock'? – Mehraban
鎖在哪裏? Invoke已經確保只有一個正在運行的進程。我想要的是停止當前的調用,如果一個新的調用 – J4N
順便說一下,你是添加**佈局刷新多個項目**?它只提供性能降低。 「Suspend/Resume」佈局有什麼問題? – AgentFire