0

Given the following piece of code:

ThreadWork thrdwrk = new ThreadWork();

Thread t = new Thread(() => thrdwrk.do_work(inc_client));
t.Start();      

What is the correct procedure, or best practice, to make sure that the thrdwrk disposal method is called? thrdwrk implements iDisposable.

If any objects contained within thrdwrk were not thread safe - would this prevent it or cause issues?

I've not been able to find any documentation that calls out specifically what the process is in this scenario.

Matheus Lacerda
  • 5,983
  • 11
  • 29
  • 45
Shovers_
  • 497
  • 2
  • 13
  • 3
    Wrap the `thrdwrk.do_work(inc_client)` inside an `using` statement. [See using](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement). – Matthiee Aug 21 '18 at 11:35
  • 1
    https://stackoverflow.com/questions/19048492/notify-when-thread-is-complete-without-locking-calling-thread You can dispose it when your thread has finished running. – Biesi Aug 21 '18 at 11:40
  • `If any objects contained within thrdwrk were not thread safe` If that is the case then why are you passing them to a new thread? – mjwills Aug 21 '18 at 11:48
  • What is an `inc_client` and how thread-safe (immutable) is it? – bommelding Aug 21 '18 at 11:53
  • _"dispose an object passed to a thread"_ should be avoided. Refactor it so that this problem goes away. – bommelding Aug 21 '18 at 11:53
  • @bommelding inc_client is a tcpclient – Shovers_ Aug 21 '18 at 12:25
  • 2
    @Shovers_ depends can you perhaps provide more code or explain in short what happends in the `do_work` method? Generally speaking you would do something like this `Thread t = new Thread(() => { using(thrdwrk) thrdwrk.do_work(inc_client); } );`. In that case the `do_work` has completed before the `using` block end and the `thrdwrk.Dispose()` gets called. – Matthiee Aug 21 '18 at 12:38
  • @Matthiee that appears to have resolved my issue now. Thanks – Shovers_ Aug 22 '18 at 10:15

1 Answers1

0

In order to prevent issues with premature disposing, the rule of thumb is that disposable objects should be disposed by whoever created them. It's counterintuitive to split the responsibility of creating/disposing of an object to two different actors.

Forgetting the threading for a second, the general idea would be to do:

ThreadWork thrdwrk = new ThreadWork();

doSomeThings(thrdwrk);

thrdwrk.Dispose();

A using pattern would be better here:

using(ThreadWork thrdwrk = new ThreadWork())
{
    doSomeThings(thrdwrk);
}

However, the threaded nature of your particular case makes it hard to gauge when the object can actually be disposed of. This is a more nuanced consideration based on the surrouding context, which is not clear from your question.

Ideally, you adhere to the rule of thumb. Wait until the thread has finished, then you know you can safely dispose of the object.

Alternatively, if you're convinced that the object should be disposed of by the thread and don't want to implement logic to wait for the thread's completion, then you should be consistent and have the thread create its own disposable object as well.
I see no benefit to creating an object in a scope where its only purpose is to pass it to a lower scope.

Flater
  • 12,908
  • 4
  • 39
  • 62