同步中断等待

时间:2013-10-09 20:26:25

标签: c# asynchronous websocket

在ASP.NET C#页面上,我有一个需要执行的异步initialAction

initialAction涉及服务器通过WebSocket发送消息,服务器应该等待一段时间,直到客户端响应。一旦响应,就应该调用onComplete。我已经完成了这部分。

如果操作未在5秒内完成其工作(例如),我希望脚本继续前进。目前,我通过反复睡眠和检查CancellationTokenSource让我的脚本在任务中等待。如果CancellationTokenSourceonComplete取消,或者已经过了5秒,则脚本将继续。

以下是我发现的最佳方法。还有更好的方法吗?

public static string wait(Action<Action<string>> initialAction)
{
    string message = null;
    using (CancellationTokenSource tokenSource = new CancellationTokenSource())
    {
        Action<string> onComplete = (msg) =>
        {
            message = msg;
            tokenSource.Cancel();
        };
        Task sleepTask = new Task(() =>
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            while (true)
            {
                if (tokenSource.IsCancellationRequested ||
                    stopwatch.ElapsedMilliseconds > 5000) { break; }
                Thread.Sleep(10);
            }
        }, tokenSource.Token);
        initialAction(onComplete);
        sleepTask.Start();
        sleepTask.Wait();
    }
    return message;
}

1 个答案:

答案 0 :(得分:1)

这比你想要的更容易。首先,将超时放入取消令牌源的构造函数中,以使其在一段时间后超时。

然后等到令牌被取消时,只需抓住令牌的等待句柄并等待它,而不是创建一个任务来对其进行spinwait。

public static string wait(Action<Action<string>> initialAction)
{
    string message = null;
    using (CancellationTokenSource tokenSource = new CancellationTokenSource(5000))
    {
        initialAction(msg =>
        {
            message = msg;
            tokenSource.Cancel();
        });
        tokenSource.Token.WaitHandle.WaitOne();
    }
    return message;
}

请注意,在两个代码段中,“中止”操作仍在继续;它没有停止,我们只是停止等待并返回null