17

Task.Delay()アプリケーションがフリーズした後、 (またはTaskEx.Delay().NET 4.0で)作成されたタスクを待機しているスレッドの原因を突き止めました。このスレッドはTimeSpan、バグのために、または以下TimeSpanのaで計算されることがありました。TotalMilliseconds等しい-1以上-2(つまり、-10000から-19999ティックの間の任意の場所)。

ミリ秒以下の負の値を渡すと、メソッドは正しくスローするTimeSpanように見えますが、上記の範囲から負のTimeSpanを指定すると、完了しないaが返されます(基になる値を-1に設定することにより)無限大を示します)。つまり、そのタスクに設定された継続は実行されず、そのタスクで発生した貧弱なスレッドは永久にブロックされます。-2ArgumentOutOfRangeExceptionTaskSystem.Threading.TimerdueTime.Wait()Task

Task決して完了しない可能性のある用途は何ですか?誰かがそのような戻り値を期待しますか?その特別な範囲の値を含め、に渡される負の値は、 ?.Delay()をスローするべきではありません。ArgumentOutOfRangeException

4

3 に答える 3

17

Timeout.Infiniteまたは-1は、完了するまでに不確定な時間がかかるが、最終的には完了する長時間実行タスクを無期限に待機する場合に役立ちます。

Win32 APIは、無限のタイムアウトに対して定数INFINITE=-1も使用します。

UIがフリーズする可能性があるため、通常はUIスレッドで使用することは望ましくありません(これは問題のようです)。ただし、ワーカースレッドには有効なユースケースがあります。たとえば、クライアントからの接続の待機をブロックしているサーバーなどです。

于 2012-05-24T17:26:05.117 に答える
7

コンソールアプリケーションを終了させたくないときに使用しています。たとえば、 Azure用のWebジョブを作成する場合、終了しないプログラムが必要です。テンプレートは次のとおりです。

public async Task Main(string args[])
{
    var timer = new Timer();
    timer.Interval = 6000;
    timer.Elapsed += (sender, args) =>
    {
        // Do something repeatedly, each 1 minute.
    };
    timer.Start();

    // Now what to do to stop the application from terminating!?
    // That's the magic:
    await Task.Delay(-1);
}
于 2019-02-11T09:46:55.080 に答える
2

Task.WhenAny()ブロック内のコードが待機中のタスクの1つを正しく処理していることを確認したいモックシナリオでは、他のタスクをモックし、無限の遅延を使用してTask.WhenAnyが処理されていることを確認できます。私がモックしなかったタスクは、無限の遅延として発生しました。

于 2015-11-25T23:32:35.140 に答える