Note that there are some explanatory texts on larger screens.

plurals
  1. POThread-safe asynchronous code in C#
    primarykey
    data
    text
    <p>I asked the question below couple of weeks ago. Now, when reviewing my question and all the answers, a very important detail jumped into my eyes: In my second code example, isn't <code>DoTheCodeThatNeedsToRunAsynchronously()</code> executed in the main (UI) thread? Doesn't the timer just wait a second and then post an event to the main thread? This would mean then that the code-that-needs-to-run-asynchronously isn't run asynchronously at all?!</p> <p><em>Original question:</em></p> <hr> <p>I have recently faced a problem multiple times and solved it in different ways, always being uncertain on whether it is thread safe or not: I need to execute a piece of C# code asynchronously. (<strong>Edit: I forgot to mention I'm using .NET 3.5!</strong>)</p> <p>That piece of code works on an object that is provided by the main thread code. <strong>(Edit: Let's assume that object is thread-safe in itself.)</strong> I'll present you two ways I tried (simplified) and <strong>have these four questions</strong>:</p> <ol> <li>What is the best way to achieve what I want? Is it one of the two or another approach?</li> <li>Is one of the two ways <em>not</em> thread-safe (I fear both...) and why?</li> <li>The first approach creates a thread and passes it the object in the constructor. Is that how I'm supposed to pass the object?</li> <li>The second approach uses a timer which doesn't provide that possibility, so I just use the local variable in the anonymous delegate. Is that safe or is it possible in theory that the reference in the variable changes before it is evaluated by the delegate code? (<strong>This is a very generic question whenever one uses anonymous delegates</strong>). In Java you are forced to declare the local variable as <strong>final</strong> (i.e. it cannot be changed once assigned). In C# there is no such possibility, is there?</li> </ol> <hr> <p><strong>Approach 1: Thread</strong></p> <pre><code>new Thread(new ParameterizedThreadStart( delegate(object parameter) { Thread.Sleep(1000); // wait a second (for a specific reason) MyObject myObject = (MyObject)parameter; DoTheCodeThatNeedsToRunAsynchronously(); myObject.ChangeSomeProperty(); })).Start(this.MyObject); </code></pre> <p>There is one problem I had with this approach: My main thread might crash, but the process still persists in the memory due to the zombie thread.</p> <hr> <p><strong>Approach 2: Timer</strong></p> <pre><code>MyObject myObject = this.MyObject; System.Timers.Timer timer = new System.Timers.Timer(); timer.Interval = 1000; timer.AutoReset = false; // i.e. only run the timer once. timer.Elapsed += new System.Timers.ElapsedEventHandler( delegate(object sender, System.Timers.ElapsedEventArgs e) { DoTheCodeThatNeedsToRunAsynchronously(); myObject.ChangeSomeProperty(); }); DoSomeStuff(); myObject = that.MyObject; // hypothetical second assignment. </code></pre> <p>The local variable <code>myObject</code> is what I'm talking about in question 4. I've added a second assignment as an example. Imagine the timer elapses <strong><em>after</em></strong> the second assigment, will the delegate code operate on <code>this.MyObject</code> or <code>that.MyObject</code>?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload