2020年11月26日
川俣晶の縁側ソフトウェアC# コーディング How Tototal 1211 count

【入門級】時間比較が失敗する場合

Written By: 川俣 晶連絡先

 サンプルソースは現在時刻の1秒後を算出し、現在時刻がそれの時間になるまで待ちます。(実際に使う時は、ただ待つだけではなく何かの処理を行います)

 本来は1秒ごとに現在時刻が表示されることを意図していますが何も出力されません。

 なぜでしょう?

 理由は、.NETの日付時刻は秒より下の桁の時間も管理しており、その微細な値が完全に一致することはほとんどないからです。

 ですから、.NETの日付時刻つまりDateTimeやDateTimeOffset型を比較する場合には、等価比較ではなく不等号で比較しなければなりません。サンプルソースにもコメントで動作するコードを入れてあります。このように、ある瞬間を越えたことを判定するようにすれば、意図した通りに1秒ごとに時間が表示されるようになります。

罠の数々 §

  • ただ待つだけならTask.Delayメソッドなどを使った方が良い。待っている間、リソースをいろいろ解放してくれて、消費電力が減り発熱も減る
  • Task.Delayメソッドは非同期なので、待ちながら別の処理を同時に実行することもできる

参考リンク §

DateTime 構造体

DateTimeOffset 構造体

 秒より下の桁がどう扱われているか、上記のリンクから辿って調べてみよう。ついでに、良く似たDateTime 構造体とDateTimeOffset 構造体の役割の違いも調べてみよう。

リポジトリ §

https://github.com/autumn009/cshowto

TimeEqual §

using System;

class Program

{

    static void Main()

    {

        for (; ; )

        {

            var target = DateTimeOffset.Now.AddSeconds(1.0);

            for (; ; )

            {

                if (DateTimeOffset.Now == target) break;

                // ↓正しいコード

                //if (DateTimeOffset.Now > target) break;

            }

            Console.WriteLine(DateTimeOffset.Now);

        }

    }

}

実行結果

(何も出力されない。よほど運が良ければ何か出る可能性はある)

Facebook

COOL C# CREW

C#ハウツー連載の解説増量、カラーのソース、新規書き下ろし追加の読みやすい単行本はこちら。

C#ハウツー: 逆引き入門・こんな機能はどう書くの?
キーワード【 川俣晶の縁側ソフトウェアC# コーディング How To
【C# コーディング How To】の次のコンテンツ
2020年
11月
27日
【入門級】プログラムの終了時に音を出して知らせる
3days 0 count
total 1927 count
【C# コーディング How To】の前のコンテンツ
2020年
11月
25日
【入門級】floatの最大値に1を足すと何が起こるのか?
3days 0 count
total 1221 count

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

https://mag.autumn.org/tb.aspx/20201126095146
サイトの表紙【C# コーディング How To】の表紙【C# コーディング How To】のコンテンツ全リスト 【C# コーディング How To】の入手全リスト 【C# コーディング How To】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.36 (Alpha-Test) Copyright (c) 2004-2021 Pie Dey.Co.,Ltd.