2017-01-25 67 views
0

我有兩個async-await連接到相同的TCP端口。互斥或信號量爲兩個不同的線程

RSP民意調查每20000ms

SP民意調查每個500ms

另一種方法,RP,每當它被調用時都會輪詢,所以它可以是隨機的。

現在,無論何時調用RP幾次,整個系統都會凍結。

我想知道,如果信號燈互斥將更適合在這種情況下,我應該如何使用它。

我已經檢查了Semaphore的例子,但它們似乎大多數使用一種方法,但試圖同時運行其中5個。我如何使用兩種不同的方法?

static SemaphoreSlim _sem = new SemaphoreSlim(1, 1); 
public async void RSP() 
{ 
    await Task.Run(() => 
    { 
     while (true) 
     { 
      _sem.Wait(); 
      //DoWork 
      _sem.Release(); 
      Thread.Sleep(20000); 
     } 
    } 
    ); 
} 

public async void SP(CancellationToken token) 
{ 
    await Task.Run(() => 
    { 
     while (true) 
     {     
      try 
      { 
       if (token.IsCancellationRequested) 
       { 
        return; 
       }   
       _sem.Wait(); 
       //DoWork 
       _sem.Release(); 
      } 
      catch (Exception) 
      { 
       if (token.IsCancellationRequested) 
       { 
        return; 
       } 
       break; 
      } 
      Thread.Sleep(500); 
     } 
    }); 
} 

回答

0

當你(默默)忽略你的catch處理Exception,不好的事情發生。

try 
{ 
    //... 
    _sem.Wait(); 
    //if an exception happens here 
    //you won't know about it because 
    //logic in the catch means it will 
    //be ignored. 
    //Even worse... the line below won't be called 
    _sem.Release(); 
} 
catch (Exception) 
{ 
    //... 
    break; //oh s**t. how will we ever know? 
} 

這是一個完美的死鎖配方。

如何改進?

try 
{ 
    //... 
    _sem.Wait(); 
    try 
    { 
     //do work 
    } 
    finally 
    { 
     _sem.Release(); //called, even if there's an exception 
    } 
} 
catch (Exception) 
{ 
    //... 
    //this is just sloppy. never ignore ALL exceptions 
    //fix this. 
    break; 
} 

順便說一句,它看起來像你做了很多同步阻塞操作,並與async await混合它們。這不是如何使用它的。有任務/異步網絡方法,它看起來像你沒有使用,你正在使用Thread.Sleep你可以使用await Task.DelaySemaphoreSlim提供了使用WaitAsync方法等待信號量的任務/異步支持。代碼中可能沒有什麼需要用等待,睡眠或同步IO來停止執行。正確學習異步並停止使用坐在等待或睡眠中的線程捆綁您的ThreadPool。