<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Cooperatively pausing async methods</title><link>http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx</link><description>Recently I was writing an app that processed a bunch of files asynchronously.&amp;#160; As with the Windows copy file dialog, I wanted to be able to provide the user with a button that would pause the processing operation. To achieve that, I implemented a</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>re: Cooperatively pausing async methods</title><link>http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx#10421719</link><pubDate>Tue, 28 May 2013 10:30:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10421719</guid><dc:creator>jods</dc:creator><description>&lt;p&gt;Note: there have been several questions on StackOverflow regarding the MSDN article and specficially the read introducion section, e.g.:&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="http://stackoverflow.com/questions/16162745/event-raising-and-read-introduction-in-net-4-5/16789697"&gt;stackoverflow.com/.../16789697&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="http://stackoverflow.com/questions/14799876/read-introduction-in-c-sharp-how-to-protect-against-it"&gt;stackoverflow.com/.../read-introduction-in-c-sharp-how-to-protect-against-it&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Maybe it&amp;#39;s best to end this discussion there.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10421719" width="1" height="1"&gt;</description></item><item><title>re: Cooperatively pausing async methods</title><link>http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx#10421133</link><pubDate>Fri, 24 May 2013 09:59:23 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10421133</guid><dc:creator>jods</dc:creator><description>&lt;p&gt;@Igor, Stephen:&lt;/p&gt;
&lt;p&gt;Sorry to come again on this topic but I was surprised when reading the MSDN Magazine (Oct 05) article &amp;#39;Understand the Impact of Low-Lock Techniques in Multithreaded Apps&amp;#39;.&lt;/p&gt;
&lt;p&gt;When describing the .net 2.0 memory model, it explicitely says:&lt;/p&gt;
&lt;p&gt;&amp;quot;Reads and writes cannot be introduced&amp;quot;&lt;/p&gt;
&lt;p&gt;Which seems to be the exact opposite of Igor&amp;#39;s statement in his article.&lt;/p&gt;
&lt;p&gt;I also found that Joe Duffy makes the same statement in his book &amp;quot;Concurrent Programming on Windows&amp;quot;, pp517-8:&lt;/p&gt;
&lt;p&gt;&amp;quot;the .NET memory model prohibits it [read introduction] for ordinary variables referring to GC heap memory&amp;quot;.&lt;/p&gt;
&lt;p&gt;So what should I conclude here?&lt;/p&gt;
&lt;p&gt;1. The memory model was weaken in .net 4? (unlikely I guess)&lt;/p&gt;
&lt;p&gt;2. The JIT optimizations may violate the CLR memory model? (which would be very dangerous)&lt;/p&gt;
&lt;p&gt;3. Igor&amp;#39;s article is incorrect about read introductions?&lt;/p&gt;
&lt;p&gt;4. Joe Duffy and Vance Morrisson are mistaken about read introductions?&lt;/p&gt;
&lt;p&gt;Thanks!&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10421133" width="1" height="1"&gt;</description></item><item><title>re: Cooperatively pausing async methods</title><link>http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx#10419083</link><pubDate>Wed, 15 May 2013 21:48:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10419083</guid><dc:creator>jods</dc:creator><description>&lt;p&gt;Thanks Igor!&lt;/p&gt;
&lt;p&gt;I read that section (§3.10 Execution Order) before but completely missed this important aspect: volatile reads and writes are side-effect.&lt;/p&gt;
&lt;p&gt;Hence they can&amp;#39;t be introduced or removed!&lt;/p&gt;
&lt;p&gt;That explains it everything.&lt;/p&gt;
&lt;p&gt;Just to be sure that I understood your answer about MemoryBarrier: introducing a read can be seen as moving a memory operation accross the barrier and this is why it&amp;#39;s forbidden, even though it&amp;#39;s not a side-effect if the variable is not volatile? E.g.&lt;/p&gt;
&lt;p&gt;var cur = memory_read;&lt;/p&gt;
&lt;p&gt;Thread.MemoryBarrier();&lt;/p&gt;
&lt;p&gt;// Accessing memory_read here is moving a memory operation accross the barrier?&lt;/p&gt;
&lt;p&gt;return cur != null ? cur.IsPaused : false; &lt;/p&gt;
&lt;p&gt;Of course Interlocked or Thread.VolatileRead are more obvious as they can&amp;#39;t be &amp;quot;repeated&amp;quot; or &amp;quot;introduced&amp;quot;.&lt;/p&gt;
&lt;p&gt;Thanks for the explanation!&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10419083" width="1" height="1"&gt;</description></item><item><title>re: Cooperatively pausing async methods</title><link>http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx#10419058</link><pubDate>Wed, 15 May 2013 20:49:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10419058</guid><dc:creator>Igor Ostrovsky - MSFT</dc:creator><description>&lt;p&gt;@jods: The reason I mentioned the &amp;quot;Publication via Volatile Field&amp;quot; section is that it describes how to safely use volatile fields. For example, the WaitWhilePausedAsync method in this article is an instance of the Publication via Volatile Fields pattern. Also take a look at the &amp;quot;Lazy Initialization&amp;quot; pattern.&lt;/p&gt;
&lt;p&gt;&amp;gt; Can you explain which rule above has been broken if &amp;quot;cur&amp;quot; in the expression &amp;quot;cur.Task&amp;quot; is read from m_paused again rather than from a temporary? &lt;/p&gt;
&lt;p&gt;Elsewhere in the C# specification, a volatile read is defined to be a &amp;quot;side effect&amp;quot;. As a result, repeating the read of m_paused would be equivalent to adding another side effect, which is not allowed.&lt;/p&gt;
&lt;p&gt;&amp;gt; Bonus chatter: how does all this relate to non-volatile variable? What if I rely on a few MemoryBarrier or Interlocked operations rather than an always volatile field?&lt;/p&gt;
&lt;p&gt;That can work too.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10419058" width="1" height="1"&gt;</description></item><item><title>re: Cooperatively pausing async methods</title><link>http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx#10419049</link><pubDate>Wed, 15 May 2013 20:21:48 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10419049</guid><dc:creator>jods</dc:creator><description>&lt;p&gt;@Igor: I read it again and it doesn&amp;#39;t explicitely talk about &amp;quot;Read introductions&amp;quot; only reorderings.&lt;/p&gt;
&lt;p&gt;The rule &amp;quot;no read is introduced that would break semantics of a volatile field&amp;quot; doesn&amp;#39;t seem sufficient to me.&lt;/p&gt;
&lt;p&gt;From my understanding of the C# standard, volatile means:&lt;/p&gt;
&lt;p&gt;[1] volatile reads have acquire semantics, i.e. no memory operation can be moved before;&lt;/p&gt;
&lt;p&gt;[2] volatile write have release semantics, i.e. no memory operation can be moved after.&lt;/p&gt;
&lt;p&gt;Add to that the rule that [3] no optimization should change the behavior of a single threaded program.&lt;/p&gt;
&lt;p&gt;Now consider Stephen&amp;#39;s code above:&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;var cur = m_paused; &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;return cur != null ? cur.Task : s_completedTask;&lt;/p&gt;
&lt;p&gt;Can you explain which rule above has been broken if &amp;quot;cur&amp;quot; in the expression &amp;quot;cur.Task&amp;quot; is read from m_paused again rather than from &lt;/p&gt;
&lt;p&gt;a temporary? &lt;/p&gt;
&lt;p&gt;Clearly rule [1] has not been violated because no memory operation has been moved before the statement &amp;quot;var cur = m_paused&amp;quot;.&lt;/p&gt;
&lt;p&gt;Rule [3] is fine as well: as long as there&amp;#39;s no other thread m_paused can&amp;#39;t have changed.&lt;/p&gt;
&lt;p&gt;Rule [2] doesn&amp;#39;t matter as there is no volatile write.&lt;/p&gt;
&lt;p&gt;Maybe the missing part of the standard is simply: no read/write can be introduced/eliminated on a volatile variable?&lt;/p&gt;
&lt;p&gt;Bonus chatter: how does all this relate to non-volatile variable? What if I rely on a few MemoryBarrier or Interlocked operations &lt;/p&gt;
&lt;p&gt;rather than an always volatile field?&lt;/p&gt;
&lt;p&gt;I think the confusion arose from the vague wording of the second article that basically states &amp;quot;read introductions -- or &lt;/p&gt;
&lt;p&gt;eliminations -- can happen in some circumstances&amp;quot; without providing the precise rules that dictate when such &lt;/p&gt;
&lt;p&gt;introduction/elimination is actually allowed or when it is forbidden.&lt;/p&gt;
&lt;p&gt;I couldn&amp;#39;t find a precise definition anywhere, information on the web only seems to focus on the ordering issues and &lt;/p&gt;
&lt;p&gt;acquire/release semantics.&lt;/p&gt;
&lt;p&gt;Or maybe it&amp;#39;s just me who doesn&amp;#39;t understand how acquire semantic and a read introduction are related?&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10419049" width="1" height="1"&gt;</description></item><item><title>re: Cooperatively pausing async methods</title><link>http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx#10419026</link><pubDate>Wed, 15 May 2013 19:33:38 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10419026</guid><dc:creator>Igor Ostrovsky - MSFT</dc:creator><description>&lt;p&gt;jods: See section &amp;quot;Publication via Volatile Field&amp;quot; of the Part 1 of my article (&lt;a rel="nofollow" target="_new" href="http://msdn.microsoft.com/en-us/magazine/jj863136.aspx"&gt;msdn.microsoft.com/.../jj863136.aspx&lt;/a&gt;). No read may be introduced that would break the acquire-release semantics of a volatile field.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10419026" width="1" height="1"&gt;</description></item><item><title>re: Cooperatively pausing async methods</title><link>http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx#10419007</link><pubDate>Wed, 15 May 2013 18:22:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10419007</guid><dc:creator>jods</dc:creator><description>&lt;p&gt;Like Gebb I would like to understand how to prevent read introductions but I&amp;#39;m not satisfied yet. I searched the web but couldn&amp;#39;t find a definitive, precise answer.&lt;/p&gt;
&lt;p&gt;This is unfortunate because it&amp;#39;s critical to write correct concurrent code. For instance your method WaitWhilePausedAsync would not be correct if a read introduction was possible.&lt;/p&gt;
&lt;p&gt;Maybe you could write a blog post on the topic?&lt;/p&gt;
&lt;p&gt;You clear the issue in the following comment above:&lt;/p&gt;
&lt;p&gt;&amp;quot;read introduction is one mechanism by which a memory reordering might be introduced&amp;quot;&lt;/p&gt;
&lt;p&gt;With the implicit argument that because a volatile variable prevents reordering, the read introduction is prevented.&lt;/p&gt;
&lt;p&gt;But!&lt;/p&gt;
&lt;p&gt;The part 1 of this article, which you&amp;#39;ve linked to, explicitely disagrees with you. It explicitely describes &amp;quot;read introduction&amp;quot; as a &amp;quot;NON-reordering optimization&amp;quot;. I quote the relevant paragraph:&lt;/p&gt;
&lt;p&gt;&amp;quot;*Non-Reordering Optimizations* Some compiler optimizations may introduce or eliminate certain memory operations. For example, the compiler might replace repeated reads of a field with a single read. Similarly, if code reads a field and stores the value in a local variable and then repeatedly reads the variable, the compiler could choose to repeatedly read the field instead.&amp;quot;&lt;/p&gt;
&lt;p&gt;If a &amp;quot;read introduction&amp;quot; is not a reordering optimization -- which makes sense -- I see nothing in the definition of a volatile variable that prevents it. Quoting the volatile explanation from the same article:&lt;/p&gt;
&lt;p&gt;&amp;quot;*Volatile Fields* The C# programming language provides volatile fields that constrain how memory operations can be reordered. The ECMA specification states that volatile fields provide acquire-­release semantics (bit.ly/NArSlt).&lt;/p&gt;
&lt;p&gt;A read of a volatile field has acquire semantics, which means it can’t be reordered with subsequent operations. The volatile read forms a one-way fence: preceding operations can pass it, but subsequent operations can’t. [...]&amp;quot;&lt;/p&gt;
&lt;p&gt;Can you please shed some light on this issue? What are the precise rules regarding read introduction, when is code safe, when is it not? &lt;/p&gt;
&lt;p&gt;Thanks!&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10419007" width="1" height="1"&gt;</description></item><item><title>re: Cooperatively pausing async methods</title><link>http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx#10392663</link><pubDate>Mon, 11 Feb 2013 16:01:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10392663</guid><dc:creator>Gebb</dc:creator><description>&lt;p&gt;Thank you, Stephen! The article doesn&amp;#39;t state explicitly that volatileness prevents read introduction, but I take it from your replies that it does. Good news.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10392663" width="1" height="1"&gt;</description></item><item><title>re: Cooperatively pausing async methods</title><link>http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx#10392654</link><pubDate>Mon, 11 Feb 2013 15:45:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10392654</guid><dc:creator>Stephen Toub - MSFT</dc:creator><description>&lt;p&gt;@Gebb: Yes, &amp;quot;read introduction&amp;quot; is one mechanism by which a memory reordering might be introduced.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10392654" width="1" height="1"&gt;</description></item><item><title>re: Cooperatively pausing async methods</title><link>http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx#10392570</link><pubDate>Mon, 11 Feb 2013 08:28:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10392570</guid><dc:creator>Gebb</dc:creator><description>&lt;p&gt;@Stephen: As I understand volatile fields prevent certain kinds of memory operations reordering. But does this concept of &amp;quot;read introduction&amp;quot; have anything to do with reordering?&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10392570" width="1" height="1"&gt;</description></item></channel></rss>