2016-03-08 43 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); 

至少要测试是否行得通?