LoginSignup
10
14

More than 5 years have passed since last update.

【C#】TaskのTimeoutの方法

Posted at

繰り返し処理のTaskのタイムアウトのより良い方法というのは何だろう?

数パターン書いてみて、一番C#らしいのはCancellationTokenSourceを使うやり方だと思いました。

都合があって.NET4.0 C#4.0です。

CancellationTokenSourceを使う

一番それらしい??
var source = new CancellationTokenSource();
//タイムアウトの設定 3秒
source.CancelAfter(3000);

Task t = Task.Factory.StartNew(() =>
{
    while(true)
    {
        source.Token.ThrowIfCancellationRequested();
        Thread.Sleep(100);//Task.Delay(100);//Delayが使えればDelayが良いな・・・。
    }
}, source.Token);

try
{
    t.Wait(source.Token);//OperationCanceledExceptionが発生します。
    //t.Wait();//AggregateExceptionが発生します。
}
catch(OperationCanceledException)
{
    Console.WriteLine("OperationCanceledExceptionが発生しました。");
}
catch(AggregateException)
{
    Console.WriteLine("AggregateExceptionが発生しました。");
}

CancellationTokenSourceを使う (微妙)

これに至る前はこう書きました。

微妙
var source = new CancellationTokenSource();

Task t = Task.Factory.StartNew(() =>
{
    while (true)
    {
        source.Token.ThrowIfCancellationRequested();
        Thread.Sleep(100);//Task.Delay(100);//Delayが使えればDelayが良いな・・・。
    }
}, source.Token);

try
{
    t.Wait(3000, source.Token);
    if (!t.IsCompleted)
    {
        source.Cancel();
        t.Wait();
    }
}
catch (OperationCanceledException)
{
    Console.WriteLine("OperationCanceledExceptionが発生しました。");
}
catch (AggregateException)
{
    Console.WriteLine("AggregateExceptionが発生しました。");
}

Waitが2つだったりtry~catchが2箇所を目的に包んでいたり。
ちょっと気持ち悪いですね。

CancellationTokenSourceを使わない

CancellationTokenSourceを使わないと何かしらの手段で自前で時間を測る必要が出てきます。

DateTimeとTimeSpan
Task t = Task.Factory.StartNew(() =>
{
    var start = DateTime.Now;
    while (true)
    {

        if(DateTime.Now - start > TimeSpan.FromMilliseconds(3000))
        {
            break;
        }
        Thread.Sleep(100);
    }
});

t.Wait();

Stopwatch
Task t = Task.Factory.StartNew(() =>
{
    var stopwatch = new System.Diagnostics.Stopwatch();
    stopwatch.Start();
    while (true)
    {

        if(stopwatch.ElapsedMilliseconds > 3000)
        {
            stopwatch.Stop();
            break;
        }
        Thread.Sleep(100);
    }
});

t.Wait();
10
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
14