Thread Safe Access to DateTime

Hello all ...

I'm working on a class to return the current date. It is a bit more complex than the following code due to managing cultures, but below is the basic idea.

My question is: how can I ensure the execution of the get property is thread-safe, without single-threading my application

My understanding from the doc that is that I need to be thread safe when using DateTime.

I was thinking that lock would be too restrictive and with a lot of calls to this class would almost single-thread my application.

Would a Read Write Lock be appropriate here Some other approach

Thanks so much for your suggestions!

Doug

using System;

using System.Collections.Generic;

using System.Text;

{

class FunCurrentDateTime

{

private DateTime myCurrentDateTime;

FunCurrentDateTime()

{

// Constructor

}

// Property

public DateTime MyCurrentDateTime

{

get

{

myCurrentDateTime = DateTime.Now;

return myCurrentDateTime;

}

} // Method

} // Class

} // Namespace




Answer this question

Thread Safe Access to DateTime

  • Eric Yeoman

    Obviously there is not point in storing the datetime, if you are going to re-get it every time anyway; so there must be other things going on in this class. You might need to post more of your code in order to determine what the most efficiently locking method would be in your scenario.

  • NeoNeo

    Wow! Thank you all very much for your responses!

    Let me elaborate a little bit more on the problem, and see if this adds to the discussion. There may be a better way to handle this; if so, please add any suggestions!

    I have an application that has multiple background threads running at the same time. At times, depending on the trace level, I would like the threads to be able to write to a single trace file so I can debug, follow activity, etc. The idea is that when a thread writes to the trace file it writes with the current date and time as part of its message, which is I guess DateTime.Now. We might be talking about a maximum of up to 10 threads. I cannot imagine a scenario with more than that.

    Let's assume for the moment that a thread will only write a one line message to the trace file. Therefore, I suppose just using DateTime.Now would be fine. However, it is just a bit more involved. I am working with globalization and localization, so when I specify a DateTime.Now value I have to use the ToString option with two parameters: A localized date format as the first and a specific culture as the second.

    These two values are obtained using a Get accessor from another singleton class named myInitConfig. Something like this:

    myCurrentDateTimeString =

    DateTime.Now.ToString

    (myInitConfig.MyResourceMgr.GetString("FullDateTimePattern".ToString()),

    myinitConfig.MyCultureInfo)

    Concern 1: While I won't be using this diagnostic option that often, I figured that I could easily timeslice on a thread in the middle of the above. So I want to make sure I'm protected. When I am running the trace, every thread will be using this to write every message, so protecting this is important. I also don't want to single-thread the world.

    Concern 2: There may be cases where I'll have a single thread write multiple diagnostic trace lines to the file. That's the reason for myCurrentDateTimeString ... to use the same DateTime for a series of multiple messages to try to tie them together for the reader. So, once this value is established, I have to protect it too.

    Suggestions on the above would be very helpful!!!

    Bonus question from the new guy: Considering the above multi-thread access scenario, would I be better off w/ a Singleton class that provided the date as per above, or having each individual class instantiate its own copy of this class and eliminate all of the locking issues We're talking a max of ten threads, and probably a pretty fair amount of verbose messages.

    Thanks for helping the newbie!

    DB



  • alansnoog

    ReaderWriterLock has greater overhead than simple monitor locks, and can only improve performance when there is a lot of lock contention (i.e., a lot of reader threads and/or very long critical sections). If you're just reading/writing a DateTime, you should definitely use a simple Monitor lock.


  • Allen Clark - MSFT

    From my point of view you would certainly need some locking mechanism to protect myCurrentDateTime. Perhaps ReaderWriterLock might be fine - depends on your scenario - hard to tell from this sample but probably yes - if you do many reads it would be a good choice (note that ReaderWriterLock still uses locks internally).

  • Dom Diaz

    DougB wrote:
    Concern 2: There may be cases where I'll have a single thread write multiple diagnostic trace lines to the file. That's the reason for myCurrentDateTimeString ... to use the same DateTime for a series of multiple messages to try to tie them together for the reader.

    So, if I understand correctly, you want your reader to always use the latest DateTime of a series of messages, instead of individual DateTimes per message.

    DougB wrote:
    So, once this value is established, I have to protect it too

    Well, you only have to 'protect' this 'value' if you store it to a field in a class that is shared by multiple threads. If you pass it as a local variable or retrieve DateTime.Now, you don't need any locks. So if you really need to store it in a field in your singleton class, I suggest you do something like this:


    private DateTime stored;

    protected DateTime Stored {
    get { lock(this) return stored; }
    set { lock(this) stored = value; }
    }

    This ensures atomic reading/writing and since DateTime is a struct (i.e., stack value), it will be copied to a (threadsafe) local variable. Note that the same works for Strings, as they are immutable, but will not for many other types. Locking overhead should be very low in this scenario, and I suggest you don't try to optimize it using thread local storage/singletons or volatile, unless you're really sure you need it.



  • Waseem Basheer

    I have some suggestions:

    Include the thread id in each line that gets logged - this way you can tell which lines belong to which threads.

    Do NOT try to bunch lines together for a single thread. This could seriously impact performance. All the good loggers I've seen log a single line per thread at a time. This may be more work for the user, but sometimes you really need to see how threads are interacting together, which will be difficult if you have introduce some articificial synchronisation. Synchronising for the sake of the log is putting the cart before the horse.

    Consider supplying a log analyser that will filter the log, e.g., on thread id. Depending on the format of the log, you can use Excel to do this (e.g., if you have comma or tab delimiters in your log lines).

    Have a look at log4net: http://logging.apache.org/log4net/.


  • Eliyahu

    If MyCurrentDateTime is the only publicly accessible method of the class, then lock would not be any more restrictive than any other locking method you might use. Although I am unclear on exactly why you are concerned about thread safety in this scenario. The DateTime.Now property is perfectly capable of functioning in a multi-threaded environment. Is there another reason you need access to this property to be synchronized

  • Thread Safe Access to DateTime