Thread in static constructor not work instantly - c#

I have a static Thread which is responsible for get and update the token from remote api. I want to start that thread in a static constructor like below
using System;
using System.Threading;
namespace StaticConstructor
{
public class CallBack
{
static string _token = "init";
static Thread _threadUpdateToken;
static CallBack()
{
_threadUpdateToken = new Thread(()=>
{
int i = 0;
while (i < 3)
{
GetTokenFromAPI();
Thread.Sleep(1 * 1000);
i++;
}
});
_threadUpdateToken.Start();
Console.WriteLine($"After thread start {DateTime.Now.ToString("hh:mm:ss")}");
Thread.Sleep(10 * 1000);
Console.WriteLine($"Static constructor keep running at {DateTime.Now.ToString("hh:mm:ss")}");
Console.WriteLine($"token = {_token}");
}
public static void GetTokenFromAPI()
{
//this is for demo purpose
var rd = new Random();
_token = rd.Next().ToString();
Console.WriteLine($"token has been updated as {_token} at {DateTime.Now.ToString("hh:mm:ss")}");
}
}
class Program
{
static void Main(string[] args)
{
CallBack cb = new CallBack();
Console.ReadKey();
}
}
}
The output is
After _threadUpdateToken.Start 05:16:15
Static constructor keeps running at 05:16:25
token = init
token has been updated as 1671358759 at 05:16:25
token has been updated as 437230378 at 05:16:26
token has been updated as 1350585644 at 05:16:27
Then my question is:
1. Why thread _threadUpdateToken not start before static Constructor finished? Is that because static Constructor must be finished before any other threads access static variables?
2. What should i do if i dont want to invoke GetTokenFromAPI() directly in static Constructor like
static CallBack()
{
GetTokenFromAPI();
}

From the C# docs:
A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
So what is happening here is that your thread will run right up to the point it tries to call the GetTokenFromAPI static method, wait until the static constructor ends and then carry on.

Related

execute after x seconds - use async task or timer ticks

currently I'm using a timer to poll every x seconds. I've seen that I could also use asyncronous tasks to execute a function after x seconds.
So I've created an example for reproduction. This is how I would use a polling timer
class UseTimer
{
public UseTimer()
{
Console.WriteLine("Foo");
Timer myTimer = new Timer(2000);
myTimer.Elapsed += (object sender, ElapsedEventArgs e) =>
{
Console.WriteLine("Bar");
myTimer.Enabled = false;
};
myTimer.Enabled = true;
Console.ReadLine();
}
}
The code first logs Foo, then waits 2 seconds for the first timer tick and then logs Bar. I tried to reproduce it by using async/await
class UseAsync
{
public UseAsync()
{
Console.WriteLine("Foo");
Do().Wait();
Console.ReadLine();
}
private async Task Do()
{
await Task.Delay(2000);
Console.WriteLine("Bar");
}
}
The behaviour seems to be the same when I test it with this code
class Program
{
static void Main(string[] args)
{
// UseAsync a = new UseAsync();
UseTimer t = new UseTimer();
}
}
I would like to know if I could or even should switch to async because it's easier to maintain and takes out complexity but remains the same way under the hood.
"Every x seconds" is different from "after x seconds".
If you need to run something (repeatedly) every x seconds, use a Timer.
If you need to run something (only once) after x seconds, use Task.Delay.
As noted in the comments, Task.Delay uses a System.Threading.Timer anyway, it's just easier to use for a single wait, and keeps your code clean.
Also, it's not wise to use asynchronous methods in a class constructor. Class constructors cannot be async, and thus you end up blocking the thread (as you did when using Wait()), or "fire and forget". If you need to do anything asynchronous while creating a new object, you can use a "factory method": a static method that creates the object for you. Then you make the constructor private to force everyone to use the factory method:
class UseAsync
{
private UseAsync() {}
public static async Task<UseAsync> CreateUseAsync()
{
var myC = new UseAsync();
await myC.Do();
return myC;
}
private async Task Do()
{
await Task.Delay(2000);
Console.WriteLine("Bar");
}
}
Then you can create an instance like this:
var a = await UseAsync.CreateUseAsync();
I've done this when I need to retrieve data from somewhere before an object is actually useful.
The console.readline should be outside useAsync method, if not the task Do will not be executed
class Program
{
static void Main(string[] args)
{
UseAsync.UseAsyn();
Console.ReadLine();
}
}
static class UseAsync
{
public static async Task UseAsyn()
{
Console.WriteLine("Foo");
await Do();
}
private static async Task Do()
{
await Task.Delay(2000);
Console.WriteLine("Bar");
}
}

C# + Overrride Delegate

I have some code that is using a third-party library that I can't bypass. This library provides some auxiliary features that I need. At this time, my code is setup like this:
static Engine engine = new Engine();
static void Main(string[] args)
{
engine.Execute(MyCode);
}
private static void MyCode()
{
// my code goes here
}
Here's my challenge: I have to instantiate some code before MyCode can use it because that instantiation must hit a database and takes longer than the threshold allowed by Engine. I can't use a static variable because multiple instances will be necessary. Which basically means, I want something like this:
static Engine engine = new Engine();
static void Main(string[] args)
{
MyClass c = new MyClass();
c.Initialize(); // This is the db call
engine.Execute(MyCode); // This line is the problem
}
private static void MyCode(MyClass c)
{
// my code goes here
c.DoStuff();
}
My problem is, I basically need to create an overloaded method that takes a parameter. However, the Execute method in the third-party library doesn't let me do that. Is there some C# syntactial way I can do this that I'm missing?
You're looking for lambda expressions:
engine.Execute(() => MyCode(c));
I'm assuming that Engine.Execute takes an instance of Action.
You could make the MyCode function an instance member function on MyClass, then pass MyClass.MyCode to Engine.Execute as an Action.
public class Engine
{
public void Execute(Action action)
{
action.Invoke();
}
}
public class MyClass
{
public void Initialize()
{
System.Threading.Thread.Sleep(500); //Simulate some work.
}
public void Run()
{
// I've renamed it from MyCode to Run, but this method is essentially your
// my code method.
Console.WriteLine($"I'm being run from the engine! My Id is {_id}.");
}
private readonly Guid _id = Guid.NewGuid();
}
public static class Program
{
static void Main(string[] args)
{
var engine = new Engine();
var c = new MyClass();
c.Initialize();
engine.Execute(c.Run);
}
}

New thread in singleton never finished

I have simple singleton class:
namespace TestApp
{
public class MySingleton
{
static MySingleton()
{
}
private static readonly MySingleton instance = new MySingleton();
private bool threadFinished = false;
public bool IsReady = false;
private MySingleton()
{
Thread t = new Thread(MyAction);
t.Start();
while (!threadFinished)
Thread.Sleep(10);
}
public static MySingleton Instance
{
get { return instance; }
}
private void MyAction()
{
threadFinished = true;
}
}
}
When I'm trying instatiate this by:
var ir = MySingleton.Instance.IsReady;
it never ends - the while loop is infinite. Why? And how to run backround thread in singleton at constructor?
You're deadlocking. You're not allowed to call any methods from another thread before the static constructor is executed. Static constructor includes the static field initalizers too.
Since you're blocking the calling thread with a while loop, static field initialization will not complete and the new thread will neither be permitted to execute MyAction either.
Your code is almost identical to this code where Eric demonstrates the deadlock.
And to quote eric's comment from same answer why does it deadlock:
#Lieven: The static constructor must run no more than once and it
must run before the first call to any static method in the class. Main
is a static method, so the main thread calls the static ctor. To
ensure it only runs once, the CLR takes out a lock that is not
released until the static ctor finishes. When the ctor starts a new
thread, that thread also calls a static method, so the CLR tries to
take the lock to see if it needs to run the ctor. The main thread
meanwhile "joins" the blocked thread, and now we have our deadlock. –
Eric Lippert Jan 17 '12 at 14:28
To answer your question; Don't do that. You gain nothing by starting a thread and waiting for it. Just simply run the method synchronously.
This works. I am not a Singleton expert - if this violates any rules, someone please point it out. But this gets around the deadlock. I copied your code into a console app, if you're using it elsewhere, adjust appropriately.
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
while (!MySingleton.Instance.IsReady)
Thread.Sleep(100);
Console.WriteLine("Done");
Console.Read();
}
}
public class MySingleton
{
static MySingleton()
{
}
private static readonly MySingleton instance = new MySingleton();
private static bool threadFinished = false;
public bool IsReady
{
get { return threadFinished; }
}
private MySingleton()
{
Thread t = new Thread(new ThreadStart(MyAction));
t.Start();
}
public static MySingleton Instance
{
get { return instance; }
}
static void MyAction()
{
threadFinished = true;
}
}
Have a look at the lock statement when you create an instance of your singleton to make it thread safe.
An example of how to use it in the singleton pattern can be found here: http://www.dofactory.com/net/singleton-design-pattern

Timer callback is still running after instance isn't reachable

After leaving the scope the thread TimerTest.exe!TimerTest.TimeClass.Callback(object state) is still running.
What is best practise to avoid such running threads?
IDisposable the class TimerClass?
Add a destructor?
Implement a method to dispose the timer?
Small Sample:
using System;
using System.Threading;
namespace TimerTest
{
internal class Program
{
private static void Main(string[] args)
{
// just a scope
{
var timerClass = new TimerClass(1);
}
Console.ReadKey();
}
}
internal class TimerClass
{
private Timer timer;
public TimerClass(int i)
{
this.timer = new Timer(Callback, i, 500, 1000);
}
private void Callback(object state)
{
Console.Out.WriteLine("Timer: " + state);
}
}
}
As you start the timer in the main thread the actually starts a new thread in the threadpool.
If you will implement IDispoable and create the timer class with using like:
(using var timerClass = new TimerClass(1))
{
your code here....
}
In the dispose method you will need to remove refence from the timer so the GC will collect this object as there will be no more refernces to this object.
The best way for my opnion is to use the IDispoe with the using...
You also can clean refenrce from timer in the callback method when you reach the amount of hits.
About the weak refernce - i am not sure that this situation fit to the defintion

AutoresetEvent and Singleton issue

Can someone please tell me what is wrong with the following code? Ideally it should start a thread first and then wait for the set event. Instead of that it does not start the thread and just get stuck on WaitOne().
I am curious to know what happened to the thread and why?
class Program
{
static void Main(string[] args)
{
Testing t = Testing.Instance;
Console.Read();
}
}
class Testing
{
private static AutoResetEvent evt = new AutoResetEvent(false);
public static Testing Instance = new Testing();
private Testing()
{
Create();
evt.WaitOne();
Console.WriteLine("out");
}
private void Create()
{
Console.WriteLine("Starting thread");
new Thread(Print).Start();
}
private void Print()
{
Console.WriteLine("started");
evt.Set();
}
}
EDIT:
So far, the description provided by #BrokenGlass makes sense. but changing the code to the following code allows another thread can access the instance methods without constructor being completed.(Suggested by #NicoSchertler).
private static Testing _Instance;
public static Testing Instance
{
get
{
if (_Instance == null)
_Instance = new Testing();
return _Instance;
}
}
I suspect the root cause of this behavior is that the spawned thread cannot access the Print method until the constructor has finished executing - but the constructor never finishes executing because it is waiting on the signal that is triggered only from the Print method.
Replacing the evt.WaitOne() with a long Thread.Sleep() call confirms the same behavior - the constructor must finish running before any instance method of the object may execute from another thread.
The problem is that the second thread is created too early. I'm not sure why, but when started before the main program starts, it will not execute.
You should use the singleton pattern in its original version. This will work.
private static Testing _Instance;
public static Testing Instance
{
get
{
if (_Instance == null)
_Instance = new Testing();
return _Instance;
}
}
Additionally, you should not make the evt variable static. The instance variable should be the only static member of a singleton class in most cases.
My guess would be an issue with the relative timing of the static field initialization. Try initializing evt in the constructor of Testing instead:
private static AutoResetEvent evt;
public static Testing Instance = new Testing();
private Testing()
{
evt = new AutoResetEvent(false);
Create();
evt.WaitOne();
Console.WriteLine("out");
}
I should note this is really just a guess- I'd have thought this code would work fine.

Categories