2016-10-20 43 views
1

我在C#中工作,我正在尋找一種機制來同步我的應用程序。我可以使用什麼同步?

我有一個函數來管理我的應用程序中的異常,在多線程上工作。當出現異常時,調用一個函數,進行一些處理並要求用戶檢查。

如果在第一個是我想等待第一和無爲後(功能已經在第一執行)

我該怎麼做正確進步的新的異常升高?

我草案:

private void onAnomaly(enumAnomaly err) 
{ 
    if (anomalyInProgress) 
     //wait 
     return; 
    else 
     anomalyInProgess = true; 
     //do something 
     anomalyInProgess = false; 
} 
+0

使用[lock](https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx) – Rob

+0

鎖正在等待第一個鎖,但在 –

+0

之後執行代碼我沒有收到此部分 - '之後什麼都不做(功能已經被執行了)'?你的意思是說,在處理第一個異常時,你想等待新的異常處理。一旦第一次異常完成後,你想開始處理新到的異常。我的理解是否正確? – RBT

回答

0

您可以使用Interlocked.Exchange method

編輯根據您的意見,您需要其他功能等待。您可以通過添加鎖定對象來完成此操作。

private int anomalyInProgress = 0; 
private Object _lock = new Object(); 

private void onAnomaly(enumAnomaly err) 
{ 
    //Here, the value of anomalyInProgress will be set to 1, but 
    // Exchange return the value before the change. 
    // So if it was 0 before, it means nobody is already executing this code 
    //and we can safely enters 
    if (0 == Interlocked.Exchange(anomalyInProgress, 1)) 
    { 
     lock (_lock) 
     { 
      //do something 

      //we reset the value of anomalyInProgress so the next one can enter in safely 
      Interlocked.Exchange(anomalyInProgress, 0) 
     } 
    } 
    else 
    { 
     //I cannot take the lock directly, because I could be taking it before the 'True' condition. 
     Threading.Thread.Sleep(1) 
     lock (_lock) //This will wait for the 'True' condition to finish 
     { 
     } 
    } 
} 
+0

正如我對Amey Kamat所說的那樣,'lock'會執行兩次(或更多次)'do something'。我想知道什麼是「做些什麼」,但不能在 –

+0

之後重做。不要忘記在完成時將anomalyInProgress設置回0,否則任何未來呼叫也將被丟棄。 – FacticiusVir

+0

@SuperPeanut我只是測試這個解決方案,我不覺得它等待第一個功能。也許我可以將此解決方案與'ManualResetEvent'混合使用,但效率和安全性如何? –

-1

當異常升高時,你調用該函數可以被鎖定

object lockObj = new object(); 
lock(lockObj) 
{ 
    //function called once anomaly raised 
} 

希望這有助於。

+0

我可能是錯的,但對於我來說,鎖正在等待函數被調用,一旦異常提出。當第一個電話結束時,第二個電話開始叫它。這幾乎是我想要的,但我該怎麼稱呼只是一次功能 –

0

我發現鎖的方式,也許不是最好的,但它似乎工作

private object anomalyLock = new object(); 
private Queue<enumAnomaly> anomalyQueue = new Queue<enumAnomaly>(); 

private void onAnomaly(enumAnomaly err) 
{ 
    anomalyQueue.Enqueue(err); 

    lock (anomalyLock) 
    { 
     if (anomalyQueue.Count == 0) 
      return; 

     //do something 

     // UserAck 

     anomalyQueue.Clear(); 
    } 
} 

有沒有最好的方法?

+2

危險!在鎖定之前,兩次異常可以立即排隊。您只能在隊列的前面處理一個,然後清除整個隊列。您甚至可能無法處理隊列中的其他異常情況。我認爲這是一種可能性,除非你透露你將如何處理隊列中的// do something部分。而且你的原始問題陳述仍然是你不想處理任何異常,直到以前的異常未完全處理。不是嗎? – RBT

+0

在這種情況下,我並不在乎在鎖定之前是否有更多的異常情況。但是你是對的,如果用戶ack和'queue.Clear'之間的異常增加,就有風險。但我沒有更好的 –

+0

你試過我提供的Interlocked.exchange解決方案嗎?我認爲它確實是你需要的... –

相關問題