0

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;
}
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 に答える