在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;
}
答案 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
。