0

On an ASP.NET C# page, I have an asynchronous initialAction that needs to performed.

initialAction involves the server sending a message over a WebSocket, and the server should wait for a while until the client responds. Once it responds, it should call onComplete. I already have this part finished.

If the action does not complete its work in 5 seconds (for example), I want the script to move on. Currently, I make my script wait in a Task by repeatedly sleeping and checking a CancellationTokenSource. If the CancellationTokenSource is canceled by onComplete or if 5 seconds has elapsed, the script will continue.

The below is the best method I've found. Is there a better way?

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;
}
4

1 回答 1

1

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

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

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

于 2013-10-09T20:30:32.787 回答