2016-03-08 96 views
1

執行我在C#下面的代碼:C#的Thread.Sleep在錯誤的位置

if (flag) 
{ 
    SendDataToExternalDevice(); 
    System.Threading.Thread.Sleep(delayValue); 
} 

SendMoreDataToExternalDevice(); 

這是非常重要的SendDataToExternalDevice()來之前SendMoreDataToExternalDevice()執行delayValue毫秒。但似乎在運行時,程序首先等待delayValue毫秒,然後運行SendDataToExternalDevice()就在之前SendMoreDataToExternalDevice()。爲什麼是這樣?我該如何解決這個問題?

PS。等待時間不一定在毫秒內(一秒鐘內就可以),但我不希望這兩個函數一個接一個地運行。

更多信息: 我修改代碼以這樣的:

if (flag) 
{ 
    for (int i=0; i<2; i++) 
    { 
    SendDataToExternalDevice(); 
    System.Threading.Thread.Sleep(1000); 
    } 
} 

SendMoreDataToExternalDevice(); 

新的代碼的結果如下:

SendDataToExternalDevice()稱爲第一次

等待1秒鐘

SendDataToExternalDevice()第二次調用

等待1秒鐘

SendMoreDataToExternalDevice()稱爲

因此,這似乎是工作的罰款。但是,當我運行了2delayValue秒的原代碼,它這樣做:

等待2秒

SendDataToExternalDevice()

SendMoreDataToExternalDevice()

+1

是否有超過1個線程?順便說一句,你分配給delayValue的值是什麼? –

+0

@Am_I_Helpful,沒有隻有一個線程。 – Arash

+2

SendMoreDataToExternalDevice()是做什麼的?你如何衡量?你可能會看到緩衝。 – SLaks

回答

-1

你可以嘗試爲避免編譯器優化,請使用全內存防護欄:

if (flag) 
{ 
    Thread.MemoryBarrier(); 
    SendDataToExternalDevice(); 
    Thread.MemoryBarrier(); 
    System.Threading.Thread.Sleep(delayValue); 
} 
SendMoreDataToExternalDevice(); 

但它感覺就像在某個地方存在解決方案中的設計缺陷。

1

我想建議一種不同類型的工作流程模式。

AutoResetEvent _waitHandle = new AutoResetEvent(true); 

public void SendDataToExternalDevice() 
{ 
    // do some work; 


    // release the lock. 
    _waitHandle.Set(); 

    // may be some more work to do 
} 

public void SendMoreDataToExternalDevice() 
{ 
    _waitHandle.WaitOne(); 
    // maye be wait addtional time here ? 

    // do send data; 
} 

,這裏是你如何處理你的處理

if (flag) 
{ 
    SendDataToExternalDevice(); 
} 
SendMoreDataToExternalDevice(); 
+0

謝謝。如果我不需要修改* SendDataToExternalDevice()*和* SendMoreDataToExternalDevice()*,那就更好了。我確實可以訪問這段代碼,並且可以改變它,如果我絕對必須這樣做,但這意味着我必須更改一大堆相關的其他代碼。在C#中沒有簡單的方法告訴編譯器將Sleep作爲一個真正的順序過程嗎?當你看到它時,不要優化或者只是運行這個東西? – Arash

+0

是的,有,使這些方法異步!並使用異步功能執行它,但它會使用線程,但代碼將是順序的。 –

0

我不知道爲什麼你的代碼工作它的方式(聽起來很奇怪,但Thread.Sleep是一個複雜的野獸),大概可以如果沒有看到更多的解決方案,就不會發現。

在此期間,你可以這樣做:

int delay = 0; 
if (flag) 
{ 
    SendDataToExternalDevice(); 
    delay = delayValue; 
} 
var timer = new System.Threading.Timer(_ => SendMoreDataToExternalDevice() 
     ,null 
     ,delay 
     ,Timeout.Infinite); 

至少要測試是否行得通?