سؤال

لقد واجهت للتو بعض السلوك غير المتوقع مع DateTime.UTCNOW أثناء إجراء بعض اختبارات الوحدة. يبدو أنه عندما تتصل بـ DateTime.now/utcnow في تتابع سريع ، يبدو أنه يعيدك نفس القيمة لفاصل زمني أطول من المتوقع ، بدلاً من التقاط زيادات أكثر دقة ميلي ثانية.

أعلم أن هناك فئة ساعة توقيت ستكون أكثر ملاءمة لإجراء قياسات زمنية محددة ، لكنني كنت فضوليًا إذا تمكن شخص ما من شرح هذا السلوك في DateTime؟ هل هناك دقة رسمية موثقة لـ DateTime.now (على سبيل المثال ، دقيقة إلى 50 مللي ثانية؟)؟ لماذا سيكون DateTime.Now أقل دقة مما يمكن أن تتعامل معه معظم ساعات وحدة المعالجة المركزية؟ ربما تم تصميمه للتو لأقل وحدة المعالجة المركزية المشتركة؟

public static void Main(string[] args)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    for (int i=0; i<1000; i++)
    {
        var now = DateTime.Now;
        Console.WriteLine(string.Format(
            "Ticks: {0}\tMilliseconds: {1}", now.Ticks, now.Millisecond));
    }

    stopwatch.Stop();
    Console.WriteLine("Stopwatch.ElapsedMilliseconds: {0}",
        stopwatch.ElapsedMilliseconds);

    Console.ReadLine();
}
هل كانت مفيدة؟

المحلول

لماذا سيكون DateTime.Now أقل دقة مما يمكن أن تتعامل معه معظم ساعات وحدة المعالجة المركزية؟

يجب أن تكون ساعة جيدة على حد سواء دقيق و دقيق; ؛ هؤلاء مختلفون. كما تذهب النكتة القديمة ، فإن الساعة المتوقفة دقيقة تمامًا مرتين في اليوم ، فإن الساعة البطيئة في الدقيقة لا تكون دقيقة أبدًا في أي وقت. لكن الساعة البطيئة في الدقيقة دقيقة دائمًا إلى أقرب دقيقة ، في حين أن الساعة المتوقفة ليس لها دقة مفيدة على الإطلاق.

لماذا يجب أن يكون وقت البيانات دقيق إلى ، قل microsecond عندما لا يمكن أن يكون دقيق إلى microsecond؟ معظم الناس ليس لديهم أي مصدر لإشارات الوقت الرسمية الدقيقة للميكروثانية. وبالتالي إعطاء ستة أرقام بعد المكان العشري الاحكام, ، آخر خمسة منها قمامة سيكون يكذب.

تذكر أن الغرض من DateTime هو تمثل موعد ووقت. توقيت الدقة العالية ليس غرضًا من وقت البيانات ؛ كما تلاحظ ، هذا هو الغرض من ساعة توقيت. الغرض من DateTime هو تمثيل تاريخ ووقت لأغراض مثل عرض الوقت الحالي للمستخدم ، وحساب عدد الأيام حتى يوم الثلاثاء المقبل ، وما إلى ذلك.

باختصار ، "ما هو الوقت؟" و "كم من الوقت استغرق ذلك؟" أسئلة مختلفة تماما. لا تستخدم أداة مصممة للإجابة على سؤال واحد للإجابة على الآخر.

شكرا على السؤال هذا سوف يجعل مقالة مدونة جيدة! :-)

نصائح أخرى

دقة DateTime خاصة إلى حد ما بالنظام الذي يتم تشغيله. ترتبط الدقة بسرعة مفتاح السياق ، والذي يميل إلى أن يكون حوالي 15 أو 16 مللي ثانية. (على نظامي ، يكون في الواقع حوالي 14 مللي ثانية من الاختبار ، لكنني رأيت بعض أجهزة الكمبيوتر المحمولة حيث تكون أقرب إلى دقة 35-40 مللي ثانية.)

كتب بيتر برومبرج مقالة عن توقيت رمز عالية الدقة في C#، الذي يناقش هذا.

أرغب في الحصول على DateTime.now الآن :) ، لذلك قمت بطهي هذا:

public class PreciseDatetime
{
    // using DateTime.Now resulted in many many log events with the same timestamp.
    // use static variables in case there are many instances of this class in use in the same program
    // (that way they will all be in sync)
    private static readonly Stopwatch myStopwatch = new Stopwatch();
    private static System.DateTime myStopwatchStartTime;

    static PreciseDatetime()
    {
        Reset();

        try
        {
            // In case the system clock gets updated
            SystemEvents.TimeChanged += SystemEvents_TimeChanged;
        }
        catch (Exception)
        {                
        }
    }

    static void SystemEvents_TimeChanged(object sender, EventArgs e)
    {
        Reset();
    }

    // SystemEvents.TimeChanged can be slow to fire (3 secs), so allow forcing of reset
    static public void Reset()
    {
        myStopwatchStartTime = System.DateTime.Now;
        myStopwatch.Restart();
    }

    public System.DateTime Now { get { return myStopwatchStartTime.Add(myStopwatch.Elapsed); } }
}

من عند MSDN ستجد ذلك DateTime.Now لديه تقريبي حل 10 مللي ثانية على جميع أنظمة التشغيل NT.

الدقة الفعلية تعتمد على الأجهزة. يمكن الحصول على دقة أفضل باستخدام QueryPerformanceCounter.

لما يستحق ، أقل من التحقق بالفعل من مصدر .NET ، قدم إريك ليبرت تعليقًا على هذا السؤال جدا قائلاً إن DateTime دقيقة فقط إلى حوالي 30 مللي ثانية. إن سبب عدم وجود نانو ثانية دقيقة ، بكلماته ، هو أنه "لا يلزم أن يكون".

من وثائق MSDN:

يعتمد حل هذه الخاصية على مؤقت النظام.

يزعمون أيضًا أن الدقة التقريبية على Windows NT 3.5 وبعد ذلك 10 مللي ثانية :)

يعتمد حل هذه الخاصية على مؤقت النظام ، والذي يعتمد على نظام التشغيل الأساسي. يميل إلى أن يكون بين 0.5 و 15 ميلي ثانية.

نتيجة لذلك ، قد تعيد المكالمات المتكررة إلى خاصية الآن في فترة زمنية قصيرة ، كما هو الحال في الحلقة ، نفس القيمة.

رابط MSDN

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top