I am just learning about Threads in C# and a question arose.
I have a TCP-Server-Class which accepts connections and passes them to a TCP-Client-Class.
The code roughly looks like this: (dummy code)
Class TcpServer
{
public static Main(string[] args)
{
while(true)
{
//I create a new instance of my "TCP-Client-Class" and pass the accepted connection to the constructor
ConnectionHandler client = new ConnectionHandler(TCPListner.acceptconnections);
//create a new Thread to handle that connection
Thread client1 = new Thread (client.handleConnection()); //and start handling it
client.start;
//Do some other stuff for protokolling
do.someOtherStuff;
// and then wait for a new connection
}
}
//Some other Methods etc.
}
Class ConnectionHandler
{
//Constructor in which a connection TCPclient connection has to be passed
public ConnectionHandler(TCPclient client)
{
//Do stuff
}
//Method to handle connection
public void handleConnections()
{
//Open streams
//.
//.
//.
//close streams
//close connections
}
}
Now to my questions:
a) Is it obligatory to close that Thread again, after it reached the "close connection" part?
b) To close a thread do I just have to call the .join Method in my main class or is there anything else I have to take care about.
c) Incase of an error, can I just simply leave the "handleConnection()" method and close that thread (ofc with appropriate error-handling)?
d) Is it important to drop the "client" reference or the "client1" reference? Or is it just consumed by the garbage collector?
Well, it's entirely fine to let the thread just complete normally. If the top-level call of a thread throws an exception, it may take down the process, depending on how the CLR is configured. It's usually better to have a top-level error handler to log the error and move on.
However, you should consider what you want to happen on shutdown:
Your while (true) loop should be changed to allow some mechanism for shutting down
If you keep track of all the threads currently handling existing requests, when you know you're trying to shut down, you can Join on them (probably with a timeout) to allow them to complete before the server finishes. However, you want to remove a thread from that collection when it completes. This sort of thing gets fiddly fairly quickly, but is definitely doable.
As an aside, it's more common to use a thread-pool for this sort of thing, rather than creating a brand new thread for each request.
Related
I have a observable object that creates a UDP socket. This object has methods to send packets from that UDP socket and a thread to listen for received packets and invoke the PacketReceived event when a packet is received. My question is how should I handle the case when close method of the observer is called while the listener thread is busy invoking PacketReceived event. I can think of 2 solutions.
Close method immediately returns and listener thread ends after finished invoking the PacketReceived event. But with this solution listener thread could be still alive after calling the close method. So after the close method returns if I try to close another object that is used in a method that subscribed to PacketReceived event there will be a chance UDP listener thread try to access it after it is closed.
Thread that calls the close method waits for the listener thread to finish its work then closes the object. So after the close method returns it is guaranteed no other listener event will be invoked. So after that thread that calls the close method can close other objects that could be used by the UDP listener thread. But the problem is if the thread that calls the close method holds a lock and UDP listener thread tries to hold the same lock while invoking there will be a deadlock.
What is the preferred solution to this problem.
The second option is the better one. For this you can use semaphores. As #Fildor has stated, we have no code to go on, so this will be a "sketch" rather than a direct solution.
It sounds like you can use a simple SemaphoreSlim object to control this problem
var semaphore = new SemaphoreSlim(1, 1);
await semaphore.WaitAsync();
try
{
// Only one thread at a time can access this.
}
...
finally
{
semaphore.Release();
}
Obviously, you are needing cross class safty here, so making a class with a semaphore that is accessable from both places shpuld be enough.
Depanding on your use case and the latency required, you could also use a ConcurrentDictionary<string, SemaphoreSlim>, that is a concurrent dictionary of semaphores - here the key would be some kind of unique identifier that the thread that calls the close method and the listner thread both have access to. Then you can do something like
private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreDictionary =
new ConcurrentDictionary<string, SemaphoreSlim>();
...
var semaphore = _semaphoreDictionary.GetOrAdd(someUniqueKeyForTheThreadPair, new SemaphoreSlim(1, 1));
await semaphore.WaitAsync();
try
{
// Only one thread at a time can access this.
}
...
finally
{
semaphore.Release();
_semaphoreDictionary.Remove(someUniqueKeyForTheThreadPair, out _);
}
Without seeing any of your code, that is the best I can offer.
I'm using a library that listens to messages by calling a method that returns a task that ends only if the a connection to the server is closed.
// Return a task that completes the connection ends
Task Listen();
The way I use listen is fire and forget, since i don't want to block on just recieving messages.
The library also provides a subscription to execute a task when it is done sending messages (basically at the end of the listen).
// Exception is null if no problem occurs during processing messages
void SubscribeToOnEnd(Func<Exception, Task> OnEnd);
In my code, I want to be able to dispose the the library object, after the fact that listen ended, or we recieved the OnEnd.
Right now I can think of 3 options:
If I call it from the OnEnd task, I'm not sure of the behaviour it could cause it is the OnEnd is called from the object that I'm trying to dispose.
Dispose the object in the continuation of the Listen() method, but I'm not sure of the consequences of this option, any side effects as option 1.
Fire a task on the OnEnd using Task.Run to dispose the object. Which is don't really think is a good practice and it may cause some synchronization issues.
What is the best practice for handling such a case ?
For simplicity imagine my code as
public class Class
{
private Library library;
public async Task MyMethod(List<string> messages)
{
// in reality this is synchronized check
if(this.library == null)
{
this.library = new Library();
this.library.SubscribeToRecieve((m) =>
{
Console.WriteLine(m);
});
this.library.SubscribeToOnEnd(this.OnEnd);
this.library.Listen();
}
foreach(var s in messages)
{
await this.library.SendAsync(s);
}
}
private Task OnEnd(Exception)
{
// do some stuff
}
}
The library object is valid for use with as long as the connection is alive, and if for any reason the connection is closed/droped, I want to be able to dispose it at that point, so when MyMethod is called again I can create another object and start listening again.
One of the things I'm having a hard time to understand in multi-threaded programming is that fact that when one thread reaches a line that calls WaitOne(), how do I know which other threads are involved? Where or how can I find (or understand) how the WaitHandle receives the signal? For example, I'm looking at this code right now:
private void RunSync(object state, ElapsedEventArgs elapsedEventArgs)
{
_mutex.WaitOne();
using (var sync = GWSSync.BuildSynchronizer(_log))
{
try
{
sync.Syncronize();
}
catch(Exception ex)
{
_log.Write(string.Format("Error during synchronization : {0}", ex));
}
}
_mutex.ReleaseMutex();
_syncTimer.Interval = TimeBeforeNextSync().TotalMilliseconds;
_syncTimer.Start();
}
There are a few methods like this in the file (i.e RunThis(), RunThat()). These methods run inside a Windows service and are called when a Timer elapses. Each of these methods are called using different Timers and set up like this:
//Synchro
var timeBeforeFirstSync = TimeBeforeNextSync();
_syncTimer = new System.Timers.Timer(timeBeforeFirstSync.TotalMilliseconds);
_syncTimer.AutoReset = false;
_syncTimer.Elapsed += RunSync;
_syncTimer.Start();
I understand that when the Timer elapses, the RunSync method will run. But when it hits the WaitOne() line, the thread is blocked. But who is it waiting for? Which "other" thread will send the signal?
WaitHandle is an abstraction, as stated in the documentation:
Encapsulates operating system–specific objects that wait for exclusive access to shared resources.
You don't know which other threads are involved, but you do know which other code is involved by checking the usage of the handle (_mutex in your case). Every WaitHandle derived class inherits WaitOne, but what happens after successful wait and how it's get signalled is specific. For instance, in your example _mutex most probably is a Mutex class, so WaitOne acts like "wait until it's free and take ownership" while the ReleaseMutex acts like "release ownership and signal". With that in mind, it should be obvious what all these methods do - ensuring that while RunThis you cannot RunThat and vise versa.
I have a class (NamedPipeManager) which has a thread (PipeThread) that waits for a NamedPipe connection using (ConnectNamedPipe) and then reads (ReadFile) - these are blocking calls (not-overlapped) - however there comes a point when I want to unblock them - for example when the calling class tries to stop the NamedPipeManager...
How can I interupt it? Using Thread.abort? Thread.interrupt? Is there a proper way to handle this?
Refer to the code below which illustrates my current situation
main()
{
NamedPipeManager np = new NamedPipeManager();
... do stuff ...
... do stuff ...
np.Stop(); // at this point I want to stop waiting on a connection
}
class NamedPipeManager
{
private Thread PipeThread;
public NamedPipeManager
{
PipeThread = new Thread(new ThreadStart(ManagePipes));
PipeThread.IsBackground = true;
PipeThread.Name = "NamedPipe Manager";
PipeThread.Start();
}
private void ManagePipes()
{
handle = CreateNamedPipe(..., PIPE_WAIT, ...);
ConnectNamedPipe(handle, null); // this is the BLOCKING call waiting for client connection
ReadFile(....); // this is the BLOCKING call to readfile after a connection has been established
}
public void Stop()
{
/// This is where I need to do my magic
/// But somehow I need to stop PipeThread
PipeThread.abort(); //?? my gut tells me this is bad
}
};
So, in function Stop() - how would I gracefully unblock the call to ConnectNamedPipe(...) or ReadFile(...)?
Any help would be appreciated.
Thanks,
It seems to be working on VC6.0, WinXP if I try to interrupt ConnectNamedPipe by
DeleteFile("\\\\.\\pipe\\yourpipehere");
So just specify name, not handle.
Starting with Windows Vista, there is a CancelSynchronousIO operation available for threads. I don't think there is a C# wrapper for it, so you would need to use PInvoke to call it.
Before Vista, there isn't really a way to perform such an operation gracefully. I would advise against using thread cancellation (which might work, but doesn't qualify as graceful). Your best approach is to use overlapped IO.
Recently I was in a situation, I could not use the Async Overlapped IO. I was stuck on the server side within ConnectNamedPipe. To unlock the thread and free resources, I had to connect to the same pipe as a client for a split second.
Main thread receives the stop signal
Main thread sets the stop event for the listening thread
Main thread connects to the pipe
If succeeded (always) - closes the newly created handle immediately
Listener thread unlocks
Listener thread does whatever required
This worked for me very well.
To unblock ReadFile one needs to connect and write to the pipe. Same effect epected.
I have an object, a Timeline, that encapsulates a thread. Events can be scheduled on the timeline; the thread will wait until it is time to execute any event, execute it, and go back to sleep (for either (a) the time it takes to get to the next event or (b) indefinitely if there are no more events).
The sleeping is handled with a WaitEventHandle, which is triggered when the list of event is altered (because the sleep delay may need to be adjusted) or when the thread should be stopped (so the thread can terminate gracefully).
The destructor calls Stop(), and I've even implemented IDisposable and Dispose() also calls Stop().
Still, when I use this component in a forms application, my application will never shut down properly when I close the form. For some reason, Stop() is never called, so neither my object's destructor triggers, nor is the Dispose() method called, before .NET decides to wait for all threads to finish.
I suppose the solution would be to explicitly call Dispose() myself on the FormClose event, but since this class is going to be in a library, and it is actually a layer deeper (that is, the application developer will never actually see the Timeline class), this seems very ugly and an extra (unnecessary) gotcha for the application developer. The using() clause, which I would normally use when resource release becomes an issue, doesn't apply as this is going to be a long-lived object.
On the one hand, I can understand that .NET will want to wait for all threads to finish before it does its final round of garbage collection, but in this case that produces a very clumsy situation.
How can I make my thread clean up after itself properly without adding requirements to consumers of my library? Put another way, how can I make .NET notify my object when the application is exiting, but before it will wait for all threads to finish?
EDIT: In response to the people saying that it is ok for the client program to be aware of the thread: I respectfully disagree.
As I said in my original post, the thread is hidden away in another object (an Animator). I instantiate an Animator for another object, and I tell it to perform animations, such as "blink this light for 800ms".
As a consumer of the Animator object, I do not care how the Animator makes sure that the light blinks for exactly 800ms. Does it start a thread? I don't care. Does it create a hidden window and use system timers (ew)? I don't care. Does it hire midgets to turn my light on and off? I don't care.
And I especially don't want to have to care that if I ever create an Animator, I have to keep track of it and call a special method when my program exits, in contrast to every other object. It should be a concern of the library implementor, not the library consumer.
EDIT: The code is actually short enough to show. I'll include it for reference, sans methods that add events to the list:
internal class Timeline : IDisposable {
private Thread eventThread;
private volatile bool active;
private SortedList<DateTime, MethodInvoker> events = new SortedList<DateTime,MethodInvoker>();
private EventWaitHandle wakeup = new EventWaitHandle(false, EventResetMode.AutoReset);
internal Timeline() {
active = true;
eventThread = new Thread(executeEvents);
eventThread.Start();
}
~Timeline() {
Dispose();
}
private DateTime NextEvent {
get {
lock(events)
return events.Keys[0];
}
}
private void executeEvents() {
while (active) {
// Process all events that are due
while (events.Count > 0 && NextEvent <= DateTime.Now) {
lock(events) {
events.Values[0]();
events.RemoveAt(0);
}
}
// Wait for the next event, or until one is scheduled
if (events.Count > 0)
wakeup.WaitOne((int)(NextEvent - DateTime.Now).TotalMilliseconds);
else
wakeup.WaitOne();
}
}
internal void Stop() {
active = false;
wakeup.Set();
}
public void Dispose() {
Stop();
}
}
Maybe set the Thread.IsBackground property to true?
eventThread = new Thread(executeEvents);
eventThread.IsBackground = true;
eventThread.Start();
Another option is to use the Interrupt method to wake it up. Just make sure that you catch the ThreadInterruptedException in the thread that you are interrupting, and that it shuts down when it happens.
active = false;
eventThread.Interrupt();
try { eventThread.Join(); } // Wait for graceful shutdown
catch (Exception) { }
Not quite sure how that EventWaitHandle of yours works though... When I did something similar once, I just used the regular Thread.Sleep =)
I don't think it is unreasonable to require clients to Stop() the thread for shutdown at all. There are ways you can create threads whose continued execution will not stop the application from exiting (although I don't have the details off the top of my head). But expecting to launch and terminate a worker thread is not too much of a burden for the client.
There is no way to get .NET to notify your thread without the clients cooperation. If you're designing your library to have a long running background thread, then the client app has to be designed to know about it.
Application::ApplicationExit is a static event, is it acceptable to listen for it and do your special cleanup work?
Implementing IDisposable should be enough indication that your clients should be using your class in a "using" block.
Implement IDisposable properly, including implementing a finaliser that calls Dispose(true). You Animator object can then do any clean up it wishes to, including stopping the thread if necessary.