同步可中断等待
本文关键字:等待 中断 同步 | 更新日期: 2023-09-27 18:34:43
在 ASP.NET C#页面上,我有一个需要执行的异步initialAction
。
initialAction
涉及服务器通过 WebSocket 发送消息,服务器应等待一段时间,直到客户端响应。 一旦它响应,它应该调用onComplete
。 我已经完成了这部分。
如果操作未在 5 秒内完成其工作(例如(,我希望脚本继续。 目前,我通过反复睡眠和检查CancellationTokenSource
来使脚本在任务中等待。 如果CancellationTokenSource
被取消onComplete
或者已经过去了 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;
}
这比你想象的要容易得多。 首先,只需将超时放入取消令牌源的构造函数中,使其在一段时间后超时。
然后,要等到令牌被取消,只需抓住令牌的等待句柄并等待它,而不是创建一个任务来对其执行旋转等待。
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
。