[英]best way to exit Thread.Sleep in the middle
i have some operation that sometimes i want to stop in the middle:我有一些操作,有时我想在中间停下来:
bool contine;
foreach (var item in this)
{
if (contine)
{
// do my stuss
}
}
The issue here that inside this foreach
sometimes i need specific delay time so i am using Thread.Sleep
.这里的问题是在这个
foreach
有时我需要特定的延迟时间,所以我使用Thread.Sleep
。 So when i stop my operation in case i am still inside this Thread.Sleep
my application is waiting until this Thread.Sleep
end and only than stop my operation so can i exit from Thread.Sleep
in the middle ?所以当我停止我的操作,以防我仍然在这个
Thread.Sleep
我的应用程序正在等待这个Thread.Sleep
结束,然后停止我的操作,所以我可以在中间退出Thread.Sleep
吗?
Update更新
The reason i need specific sleep is because i am play packets and between every packets there is a Time stamp
so this is why i need this sleep.我需要特定睡眠的原因是因为我正在播放数据包,并且每个数据包之间都有一个
Time stamp
所以这就是我需要此睡眠的原因。
You can use Task.Delay which also can be canceled.您可以使用也可以取消的 Task.Delay。
private void Method(CancellationToken token)
{
foreach (var item in this)
{
if (!token.IsCancellationRequested)
{
// do my stuss
Task.Delay(1000, token).Wait(); // use await for async method
}
else break; // end
}
}
When you want to call当你想打电话时
var source = new CancellationTokenSource();
Method(source.Token);
And when you want to cancel.当你想取消时。
source.Cancel();
For those who are using Framework .Net 4.0,对于那些使用 Framework .Net 4.0 的人,
I've adapted the accepted answer with the enhancement that, it can be restarted any times because TokenSource
is discarded and recreated for each call to Method(...)
.我已经通过增强修改了接受的答案,它可以随时重新启动,因为每次调用
Method(...)
都会丢弃并重新创建TokenSource
。
Using Microsoft.Bcl.Async v1.0.168 for .NET Framework 4 (with KB2468871)将Microsoft.Bcl.Async v1.0.168用于 .NET Framework 4(使用 KB2468871)
public CancellationTokenSource TokenSource = null;
...
await Method(TokenSource);
...
// Somewhere else, cancel the operation
TokenSource?.Cancel();
...
async void Method(CancellationTokenSource tokenSource)
{
try
{
// Create a new CancellationTokenSource each time starting the new work stuff
tokenSource = new CancellationTokenSource();
foreach (var item in this)
{
if (!tokenSource.IsCancellationRequested)
{
// Do work stuff
...
// Using await for async method to make UI responsive while waiting
await Task.Factory.StartNew(() =>
{
tokenSource.Token.WaitHandle.WaitOne(TimeSpan.FromMilliseconds(1000));
});
}
else
break;
}
finally
{
// Release the tokenSource to reuse a new one nex time method is called
tokenSource.Dispose();
}
}
Regards.问候。
One possible solution could be to use your own Sleep
method like (needs to be improved for sure!):一种可能的解决方案是使用您自己的
Sleep
方法,例如(确实需要改进!):
/// <summary>
/// Contains extensions for threads.
/// </summary>
public static class ThreadExtensions
{
/// <summary>
/// Allows sleeping with cancellation.
/// </summary>
/// <param name="thread">The reference to the thread itself.</param>
/// <param name="sleep">The amount of time to sleep in milliseconds.</param>
/// <param name="source">An instance of <see cref="CancellationTokenSource"/> which can be used to signal the cancellation.</param>
public static void InterruptableSleep(this Thread thread, int sleep, CancellationTokenSource source)
{
while (!source.IsCancellationRequested && (sleep -= 5) > 0)
{
Thread.Sleep(5);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.