0

I have a class which has the purpose of providing file operations i.e. providing functionality to create the file, read, write and rewrite to the file. So, the main constituent of the class is functions.

However, there is one functionality where I am using a Timer to make the thread wait for one second. So, basically I have an AutoResetEvent and Timer working in conjunction.

Now, since we have to register the Timer_Elapsed callback to the Timer, we need a place to do it. Since the class is static, I can use a static constructor to do that but this makes me think whether the class should be static at first place.

I am confused whether to make the class static or non-static as it is mostly about giving simple functionality but at the same time Timer and AutoResetEvent have become kind of state elements of the class. I would appreciate suggestions.

Edit Reason why I am using a Timer is:

I am trying to synchronize file access between two processes by using FileShare.None. In order to do that I am in a loop to reattempt to gain access to the FileStream for which I have to wait 1 second each iteration. I am developing functionality in legacy code so I want to avoid Thread.Sleep. Also I know that a mutex would be a better option to synchronize access to a file but I cannot use it as I have so many such files that creating a mutex for each is not preferred (I am asked to not create mutex).

9
  • Generally speaking, I prefer to chose the singleton approach than having a static class so it can be injected (as an interface) and mocked more easily for tests and your logic code isn't tightly coupled to your persistence/data access layer.
    – jeromej
    Commented Feb 13, 2020 at 8:42
  • 1
    Try to move the functionality with the timer and the AutoResetEvent into a separate class which is not static.
    – helb
    Commented Feb 13, 2020 at 8:47
  • 1
    @JeromeJ I am dealing with legacy code and unit tests are far from reality....I also think that singleton injection is best but since I am with legacy do you think static would be fine? Commented Feb 13, 2020 at 8:51
  • @helb Would you then inject the class object with timer code using a static constructor in the File operations class? Commented Feb 13, 2020 at 9:01
  • No, you can't pass arguments to the static constructor. You may pass it to an Init() method or just instantiate it in the static contructor.
    – helb
    Commented Feb 13, 2020 at 9:04

3 Answers 3

3

Turning this comment into an answer as OP accepted it as a viable answer.


I'm unsure about your reasoning to avoid Thread.Sleep (as per the comments on the answer) Are you expecting to run multithreaded?

  • If no, then your single thread will always block for a second, regardless of how you do it.
  • If yes, then sleeping one thread will not impact the other thread.

So in either case, I don't see a reason to discount Thread.Sleep as a viable solution.


In response to your comment:

@Flater yeah agree, but when we do Thread.Sleep we make the thread not reusable.

Note that await Task.Delay(1000); works equally well as Thread.Sleep(1000). However, if you are limited to a single thread, this can lead to your sleeping task to not be picked up for longer than a second.

Essentially, when you delay, the thread will look for another task to work on. However, it will not look back at the original task until its current task is being delayed as well. If the new task is long-running, then it may take some time for your original task to be picked up again.

But when you sleep (instead of delay), then the current tasks remains the current task, nothing else will be pickd up in the mean time, and the thread will resume after exactly a second.

Maybe that's okay, maybe it's not. I don't know enough about your circumstances to make that call. But consider which one is more appropriate for your case.

0

I've read you mention the codebase is legacy.

I came up with a workaround.

Since this operation is inside of a Thread.

Thread.Sleep could be another way for waiting one second, and you don't have to deal with timer.

Sorry, I can't comment it for less than 50 reputation.

11
  • Yes, but I wanted to avoid Thread.Sleep and introduce timer. Commented Feb 13, 2020 at 10:14
  • Opps, then I shall remove this post.
    – Louis Go
    Commented Feb 13, 2020 at 10:15
  • By the way, why do you want to avoid Thread.Sleep?
    – Louis Go
    Commented Feb 13, 2020 at 10:16
  • The thread on which the code will execute already has a lot of code i.e it is being executed from a very big function....in order to not mess up and not to introduce any unexpected devil for me I would prefer a notification based waiting Commented Feb 13, 2020 at 10:18
  • If it's a thread, no matter how you implement your wait, you still have to pending this thread for one second. Am I missing any of your prerequisite? Is there a way to run many tasks on single thread?
    – Louis Go
    Commented Feb 13, 2020 at 10:23
0

In C++, if you have a static instance of a class, and exit the application, the destructor for the class will be called, possibly while the static instance is still running other code, with possibly fatal results.

I would avoid static instances especially when timers or anything multithreaded is involved.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.