繁体   English   中英

在中间退出 Thread.Sleep 的最佳方式

[英]best way to exit Thread.Sleep in the middle

我有一些操作,有时我想在中间停下来:

bool contine;
foreach (var item in this)
{
    if (contine)
    {
        // do my stuss
    }
}   

这里的问题是在这个foreach有时我需要特定的延迟时间,所以我使用Thread.Sleep 所以当我停止我的操作,以防我仍然在这个Thread.Sleep我的应用程序正在等待这个Thread.Sleep结束,然后停止我的操作,所以我可以在中间退出Thread.Sleep吗?

更新

我需要特定睡眠的原因是因为我正在播放数据包,并且每个数据包之间都有一个Time stamp所以这就是我需要此睡眠的原因。

您可以使用也可以取消的 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();

对于那些使用 Framework .Net 4.0 的人,

我已经通过增强修改了接受的答案,它可以随时重新启动,因为每次调用Method(...)都会丢弃并重新创建TokenSource

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();
        }       
}

问候。

一种可能的解决方案是使用您自己的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM