Your first attempt is pretty good, but the stream continued to exist even after the application IsBackground , because you did not set the IsBackground property to true ... here is a simplified (and improved) version of your code:
MyObject myObject = this.MyObject; Thread t = new Thread(()=> { Thread.Sleep(1000); // wait a second (for a specific reason) DoTheCodeThatNeedsToRunAsynchronously(); myObject.ChangeSomeProperty(); }); t.IsBackground = true; t.Start();
As for thread safety: it's hard to say if your program is working properly when multiple threads are running at the same time because you are not showing us any match points in your example. It is very likely that you will encounter concurrency problems if your program has competition on MyObject .
Java has the final keyword, and C # has the corresponding keyword named readonly , but neither final nor readonly guarantees that the state of the mutable object will be consistent between threads. The only thing these keywords do is ensure that you do not change the link that the object points to. If two threads have read / write conflicts on the same object, then to ensure thread safety, you need to perform some synchronization or atom operations.
Update
OK, if you change the link that MyObject points to, then your dispute is now included in MyObject . I am sure that my answer will not be 100% in your real situation, but given the example code given, I can tell you what will happen:
You are not guaranteed which object will be modified: it can be that.MyObject or this.MyObject . This is true if you are working with Java or C #. A scheduler can schedule your thread / timer to run before, after, or during a second assignment. If you are counting on a specific execution order, then you need to do something to ensure that the execution order is executed. Usually something is the connection between the flows in the form of a signal: a ManualResetEvent , Join or something else.
Here is an example connection:
MyObject myObject = this.MyObject; Thread task = new Thread(()=> { Thread.Sleep(1000);
Here is an example of ManualResetEvent :
ManualResetEvent done = new ManualResetEvent(false); MyObject myObject = this.MyObject; Thread task = new Thread(()=> { Thread.Sleep(1000);
Of course, in this case itβs pointless even to create several threads, since you do not allow them to start at the same time. One way to avoid this is to not change the link to MyObject after you start the stream, then you do not need Join or WaitOne on ManualResetEvent .
So this leads me to the question: why are you assigning a new MyObject ? Is this part of a for loop that runs multiple threads to perform multiple asynchronous tasks?