簡體   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