我有一些操作,有时我想停在中间:
bool contine;
foreach (var item in this)
{
if (contine)
{
// do my stuss
}
}
此问题在foreach
内有时我需要特定的延迟时间,所以我使用的是Thread.Sleep
。
所以当我停止我的操作以防我仍然在这个Thread.Sleep
内时,我的应用程序正在等待Thread.Sleep
结束并且只停止我的操作,所以我可以退出中间的Thread.Sleep
吗?
更新
我需要特定睡眠的原因是因为我正在播放数据包,并且每个数据包之间都有一个Time stamp
所以这就是我需要睡眠的原因。
答案 0 :(得分:6)
您可以使用也可以取消的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
}
}
当你想打电话时
var source = new CancellationTokenSource();
Method(source.Token);
当你想要取消时。
source.Cancel();
答案 1 :(得分:0)
一种可能的解决方案可能是使用您自己的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);
}
}
}
答案 2 :(得分:0)
对于使用Framework .Net 4.0的用户,
我对接受的答案进行了调整,使其具有增强功能,因为TokenSource
会被丢弃,并且每次调用Method(...)
都会重新创建,因此可以随时重新启动。
将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();
}
}
致谢。