Should I implement IDisposable for a class containing Thread

I have a class that uses the Thread class:

class A { public Thread thread { get; set; } } 

Should I implement IDisposable and set the Thread property to null?

 class A : IDisposable { public Thread Thread { get; set; } protected bool Disposed { get; set; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!this.Disposed) { if (disposing) { if (Thread != null) Thread = null; } Disposed = true; } } } 

Or not?
Why?

+6
source share
2 answers

You only implement IDisposable when your class processes an unmanaged object, resources, or other IDisposable objects. A thread is not an unmanaged object and collects garbage if nothing refers to it or when process processing is terminated. Since Thread does not implement IDisposable , your class referencing it also does not need to implement it.

Optionally, for IDisposable within a method, they can be wrapped in a using statement, and the Dispose () method is automatically called when the scope is completed.

+8
source

It depends on what your thread is doing. If your thread is performing a long-term task that can be performed indefinitely, I would consider this thread as a resource (which will not be garbage collected). For example, consider whether a thread is allowed to poll a certain state indefinitely or because of consumption of items from the queue (for example, a thread-pool thread consumes tasks or a TCP server consumes new connections), etc. In this case, I would say that the natural effect of getting rid of your class would be to free this thread resource. Setting this value to zero is not very useful in this case. Rather, Dispose should probably include the tagging of a synchronization event (or perhaps a CancellationToken) to notify the thread that it should complete its infinite task, and then the allocation thread should wait a while for the thread to finish (joining). As always with joins, be careful with the deadlock scenario and consider some alternative actions if the thread refuses to stop working. For obvious reasons, I would not join the finalizer.

As an example of what I mean, consider a scenario where your class A is actually a class MyTcpListener designed to listen and wait for new TCP connections on this port for an unlimited time. Then consider what you expect from the following (somewhat unlikely) code:

 using (MyTcpListener listener = new MyTcpListener(port:1234)) { // Do something here } // Create another one. This would fail if the previous Dispose // did not unbind from the port. using (MyTcpListener listener = new MyTcpListener(port:1234)) { // Do something else here } 

Assuming that I know that the MyTcpListener constructor creates a listener thread, I would expect that after the Dispose call returns, MyTcpListener will no longer be bound to the TCP port, i.e. The TCP listener thread would be completely terminated. It goes without saying that if you have not provided any mechanism to stop the listener, there will be a resource leak. The stop mechanism may be a call to some Stop method, but I personally think that the Dispose pattern is more clean for this scenario, because forgetting to stop something usually does not mean a resource leak.

Your code may cause various assumptions, so I would suggest judging it by the script. If your thread is running for a short time, i.e. he has some known final task to complete, and then it will end on its own, then I would say that the order is less critical or perhaps useless.

+2
source

All Articles