I have a piece of code where I send a file content over tcp/ip channel. There are times when this connection hangs causing entire application to freeze. Is there a way for my main thread to spawn a worker thread and monitor that worker thread. If worker thread succeeds, well and good. If it hangs , the main thread could log error message and continue. How can I simulate in my test code that a worker thread is hanging. please let me know what could the code look like. I am using C# Visual studio 2002.
Surely this is possible.
Either you implement threading manually using the BackgroudWorker or Thread class or (in your case even simpler) you use the asynchroneous methods for sending your content.
All the network related classes contain asynchroneous methods for their operations. Look for the methods that contain Async or Begin...
And simulating a dead thread is simple. Just make an endless loop:
while (true)
System.Threading.Thread.Sleep (10);
Related
In another SO question, I was advised to send an asynchronous network request, rather than sending a synchronous request on a background thread. The reason was so that I don't waste a thread. I'm trying to understand how this is so.
This is the original approach. I can understand how there are two threads here. One is the main thread (1), and one is the background thread (Task.Run) (2) that makes the WCF call:
This is my sketch of the suggested approach. I'm trying to understand how a thread is saved. After the async WCF call, won't another thread be created for the callback from the async WCF call?
After thinking about this further, perhaps only one thread is used if callback processing isn't necessary?
In your WPF client you likely have a OnClick somewhere in your client, where is the thread that is checking if the client was clicked or not?
The answer to that the OS itself is checking for the click then passing the message along to to the message pump which in turn invokes your function. The callback for the WCF function is like that, the OS itself is listening for the reply message and when it gets one it will send a signal that will find a free thread on the thread pool and execute the callback at that time.
The major difference between synchronously holding the thread and letting the callback method generate a thread at the end is the fact that the thread pool is a pool. When a thread in the thread pool finishes its work it does not get destroyed, it waits around a while to see if more work is available to be done and it will be reused to do that new work.
So the two choices are
Have 1 Thread sit there waiting doing no other work waiting for the function to unblock (Sync + thread)
Reuse an existing thread that has finished it's work already (or spawn a new one if none are waiting and we are below ThreadPool.GetMaxThreads()) when the OS tells us the information we where waiting for has shown up, give it the short task of handling the callback, then letting the thread go back in to the pool to do other work for other callbacks as they come in.
I have a program that retrieves data from a serial device, and then puts it in a server that is accessible by certain programs that can handle this protocol. This server is a third party program that is in the form of an active x control.
The hardware devices require a Thread.Sleep, which is unfortunate. The programs that monitor the server sometimes query the server during the time when a thread is sleeping. This causes it to think the server has failed.
My next idea was to put the server on a separate thread, one solely dedicated for the server tasks. In the UI thread, I run the following code:
Thread workerThread = new Thread(DoServerWork);
workerThread.SetApartmentState(ApartmentState.STA);
workerThread.Start();
In the delegate, I have
public void DoServerWork()
{
rtu = new AxASMBSLVLib.AxASMBSLV();
rtu.CreateControl();
rtu.BeginInit();
rtu.OpenPort();
while (true)
{
}
}
The problem is that the server starts to work, and then becomes unresponsive in about 5 seconds. My initial thought is that the thread is exiting, but the while(true) should prevent that from happening. Any thoughts?
Since you are running this in a Single Threaded Apartment (STA), once that thread hits the empty endless loop, nothing more can happen. An endless loop is generally not a good idea. You should probably use a timer to periodically perform the server work in its OnElapsed event handler.
It is a modbus TCP/IP slave from a third party company. The first option is to "drag and drop" it from the toolbox to the GUI, causing it to be on the UI thread.
Since ActiveX requires STA : exactly the right thing.
I must call Thread.Sleep on the UI thread,
that should never be necessary, here lies your real problem. Never block/sleep he main thread.
Your question should be about how to avoid the Sleep().
I have a Borland C++ project where I see a synchronize() method which a worker thread can use to delegate a task to main thread and wait for task to complete. In C#, there is a similar Control.Invoke() method. Is there anything similar while working in C++ in Visual Studio for both GUI and Console applications? SendMessage() comes to my mind but is that equivalent of above two?
SendMessage is OK for GUI applications, where main thread has a message queue. For Console applications there is no generic way. You need to decide first, how main thread should handle such requests. If main thread of the Console application has message queue, SendMessage is OK as well. You can think about another ways, for example, using events, everytning depends on the main application thread behavior and its ability to handle requests from another threads.
I am using the class HttpListener as a web server. This server runs on a different thread.
At some point this server needs to run some code but it needs to be executed on the main thread. Is there an easy way of doing that?
Thanks!
The bigger question is:
Why do you need to run it on the parent thread? Is it UI Code modifying the UI? Do you need to be within that thread's context to gaurantee thread saftey?
It might be worth stepping back and re-evaluating your threading model, you may be trying to do things in the wrong place.
I Suggest you read This Excelent Free E-Book on C# Threading and learn about the alternate ways of inter-thread communication and look into the Dispatcher if you're using WPF, as it will help delegate events back to the UI Thread if that's what your intent is.
Quick & Dirty Solution Not really the best way
There's any number of ways to approach this, the simplest would probably to have a list of delegates to execute on the main thread. Each time your main thread spins, you lock the collection (unless you're using the multi-threaded collections) and copy out the delegates & clear the collection and release the lock.
Then you simply run them on the main thread.
The problem you'll run into is if you're using blocking on the main thread, your spin cycle will not pass across your delegates till your blocking stops. So if you're say, blocking while you wait for connections, your code will not run till a new person connects.
You could put the server's listen port on it's own thread to solve this.
To do something on the main thread, you will possibly want to inject it via Invoke(), or in the main loop will have some queue of things to do that will be injected from the 'other' threads, in this case HttpListener.
Your example seems similar to mine, where I have 300 threads handling stream ripping, and they are all 'calling' main thread by putting the string messages into the queue for it. It works like a charm. However, when I did try (I dared, just to see what will happen) to Invoke() from at least 30-ish threads to the main message loop, it was weird, to say the least.
Best: use simple Queue< something >, and enqueue it from the other thread, then dequeue it from the UI thread.
I have this simple code:
public void Run()
{
var invokerThread = new Thread(new ThreadStart(RunOnBackground));
invokerThread.Start();
}
private void RunOnBackground()
{
Trace.WriteLine("hi");
...
}
Unfortunately when running this code (from third party process) the thread doesn't really run.
Either in process explorer and in VS debugger I see that the thread is created and its state is "Running".
The main thread's apartment is STA and I've tried both STA and MTA on internal thread.
When I add to the Run() method at the end invokerThread.Join(); then the thread does run. But then again it doesn't really help.
What am I missing?
Edit: Here is some more information regarding the code hosting -
Run() method is called via COM interop from a process which is also managed executable assembly (the reason COM interop is used is because all other components in the system are native).
The method RunOnBackground() includes some more code after the tracing and generally its execution lasts between 10 - 20 seconds, including starting another process and waiting for its termination. Also I have some other areas in the code where I write some debug information to the Trace. While debugging the code, Run() runs as usual and after invokerThread.Start(); invokerThread's state is "Running" (though breakpoints inside the RunOnBackground() method don't stop).
When I add invokerThread.Join() at the end of the Run() method the debugger goes to RunOnBackground() after the Join().
There's some crucial information missing about what RunOnBackground() really does. This is otherwise a good match for what happens when you use apartment threaded COM objects on a worker thread. COM automatically marshals any method call on such an object from the worker thread to the STA thread on which it was created.
That can only work well when the STA thread observes STA threading requirements. It must pump a message loop and cannot block. Breaking those rules makes deadlock very likely, the worker thread call cannot complete until the STA thread dispatches the marshaled call. A sure sign that this is what is going on is seeing Thread.Join() solve the problem. It pumps a message loop internally in the CLR when it is called on an STA thread.
To diagnose this, you'll need Debug + Windows + Threads to see what that worker thread is blocking on. If my guess is right, it will be buried deep inside of the COM plumbing code, waiting for the marshaled call to complete. You can only see this by enabling unmanaged code debugging and setting up the Microsoft Symbol Server so you get debugging symbols for the plumbing code and get a reliable stack trace.
Fixing this is going to be difficult. You cannot magically flip a switch and make code run on a thread when it has explicitly stated that it doesn't support multi-threading. It is imperative that you create the instance of the COM object on the same thread that calls its methods. And that thread has to be an STA thread. Check this sample code for the approach. If you don't control the creation of the COM object then you're stuck.
I may say something stupid, but here is what I saw in MSDN Threads.
Look at the examples section at the end.
The output of the example is interesting, you can see there that the Thread created and started only starts executing when the main thread does a Sleep(0) or a Thread.Join().
It seems to be what exactly happens to you, doesn't it ?
Maybe try with a Sleep(0) on your main thread to really launch your working Thread.
Another workaround would be to use the BackGroundWorker.
As its name says it, it works on the Background and is really easy to use. It may be of much use to you.