{"id":243,"date":"2014-08-14T07:00:00","date_gmt":"2014-08-14T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/08\/14\/customers-not-getting-the-widgets-they-paid-for-if-they-click-too-fast-or-in-c-the-operator-is-not-merely-not-guaranteed-to-be-atomic-it-is-guaranteed-not-to-be-atomic\/"},"modified":"2014-08-14T07:00:00","modified_gmt":"2014-08-14T07:00:00","slug":"customers-not-getting-the-widgets-they-paid-for-if-they-click-too-fast-or-in-c-the-operator-is-not-merely-not-guaranteed-to-be-atomic-it-is-guaranteed-not-to-be-atomic","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140814-00\/?p=243\/","title":{"rendered":"Customers not getting the widgets they paid for if they click too fast -or- In C#, the += operator is not merely not guaranteed to be atomic, it is guaranteed not to be atomic"},"content":{"rendered":"<p>In the C# language, operation\/assignment such as <code>+=<\/code>\nare explicitly <i>not<\/i> atomic.\nBut you already knew this, at least for properties.\n<\/p>\n<p>\nRecall that properties are syntactic sugar for method calls.\nA property declaration\n<\/p>\n<pre>\nstring Name { get { ... } set { ... } }\n<\/pre>\n<p>\nis internally converted to the equivalent of<\/p>\n<pre>\nstring get_Name() { ... }\nvoid set_Name(string value) { ... }\n<\/pre>\n<p>\nAccessing a property is similarly transformed.\n<\/p>\n<pre>\n\/\/ o.Name = \"fred\";\no.put_Name(\"fred\");\n\/\/ x = o.Name;\nx = o.get_Name();\n<\/pre>\n<p>\nNote that the only operations you can provide for properties\nare <code>get<\/code> and <code>set<\/code>.\nThere is no way of customizing any other operations, like\n<code>+=<\/code>.\nTherefore, if you write\n<\/p>\n<pre>\no.Name += \", Jr.\";\n<\/pre>\n<p>\nthe compiler has no choice but to convert it to\n<\/p>\n<pre>\no.put_Name(o.get_Name() + \", Jr.\");\n<\/pre>\n<p>\nIf all you have is a hammer, everything needs to be converted to a nail.\n<\/p>\n<p>\nSince the read and write are explicitly decoupled, there is naturally\na race condition here.\nThe underlying property may change value in between the time you read\nthe old value and the time you write the new value.\n<\/p>\n<p>\nBut there are extra subtleties here.\nLet&#8217;s dig in.\n<\/p>\n<p>\nThe rule for operators like <code>+=<\/code> are spelled out in\n<a HREF=\"http:\/\/www.jaggersoft.com\/csharp_standard\/14.13.2.htm\">\n<i>Section 14.3.2: Compound Assignment<\/i><\/a>:\n<\/p>\n<blockquote CLASS=\"q\"><p>\n[T]he operation is evaluated as x = x op y,\nexcept that x is evaluated only once.\n<\/p><\/blockquote>\n<p>\n(There is some discussion of what &#8220;evaluated only once&#8221; means,\nbut that&#8217;s not important here.)\n<\/p>\n<p>\nThe subtleties lurking in that one sentence\nare revealed when you see how that sentence interacts\nwith other rules in the language.\n<\/p>\n<p>\nNow, you might say,\n&#8220;Sure, it&#8217;s not atomic, but my program is single-threaded,\nso this should never affect me.&#8221;\n<\/p>\n<p>\nActually, you can get bitten by this even in single-threaded programs.\nLet&#8217;s try it:\n<\/p>\n<pre>\nclass Program\n{\n static int x = 0;\n static int f()\n {\n  x = x + 10;\n  return 1;\n }\n public static void Main()\n {\n  x += f();\n  System.Console.WriteLine(x);\n }\n}\n<\/pre>\n<p>\nWhat does this program print?\n<\/p>\n<p>\nYou might na&iuml;vely think that it prints <code>11<\/code>\nbecause <code>x<\/code> is incremented by 1 by <code>Main<\/code>\nand incremented by 10 in <code>f<\/code>.\n<\/p>\n<p>\nBut it actually prints 1.\n<\/p>\n<p>\nWhat happened here?\n<\/p>\n<p>\nRecall that C# uses\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2007\/08\/14\/4374222.aspx\">\nstrict left-to-right evaluation order<\/a>.\nTherefore, the order of operations in the evaluation of\n<code>x += f()<\/code> is\n<\/p>\n<ol TYPE=\"1\">\n<li>Rewrite as <code>x = x + f()<\/code>.\n<li>Evaluate both sides of the <code>=<\/code> operator, left to right.\n<ol TYPE=\"a\">\n<li>Left hand side of assignment: Find the variable <code>x<\/code>.\n<li>Right hand side of assignment:\n<ol TYPE=\"i\">\n<li>Evaluate both sides of the <code>+<\/code> operator, left to right.\n<ol TYPE=\"1\">\n<li>Evaluate <code>x<\/code>.\n<li>Evaluate <code>f()<\/code>.\n            <\/ol>\n<li>Add together the results of steps 2b(i)1 and 2b(i)2.\n        <\/ol>\n<\/ol>\n<li>Take the result of step 2b(ii) and assign it to\n        the variable <code>x<\/code> found in step 2a.\n<\/ol>\n<p>\nThe thing to notice is that a lot of things can happen between step\n2b(i)1 (evaluating the old value of <code>x<\/code>),\nand step 3 (assigning the final result to <code>x<\/code>).\nSpecifically,\nwe shoved a whole function call in there: <code>f()<\/code>.\n<\/p>\n<p>\nIn our case, the function\n<code>f()<\/code> <i>also modifies <code>x<\/code><\/i>.\nThat modification takes place after we already captured the\nvalue of <code>x<\/code> in step 2b(i)1.\nWhen we get around to adding the values in step 2b(ii),\nwe don&#8217;t realize that the values are out of date.\n<\/p>\n<p>\nLet&#8217;s step through this evaluation in our example.\n<\/p>\n<ol TYPE=\"1\">\n<li>Rewrite as <code>x = x + f()<\/code>.\n<li>Evaluate both sides of the <code>=<\/code> operator, left to right.\n<ol TYPE=\"a\">\n<li>Left hand side of assignment: Find the variable <code>x<\/code>.\n<li>Right hand side of assignment:\n<ol TYPE=\"i\">\n<li>Evaluate both sides of the <code>+<\/code> operator, left to right.\n<ol TYPE=\"1\">\n<li>Evaluate <code>x<\/code>. The result is 0.\n<li>Evaluate <code>f()<\/code>. The result is 1.\n                It also happens that <code>x<\/code> is modified as a\n                side-effect.\n            <\/ol>\n<li>Add together the results of steps 2b(i)1 and 2b(i)2.\n            In this case, 0 + 1 = 1.\n        <\/ol>\n<\/ol>\n<li>Take the result of step 2b and assign it to\n        the variable <code>x<\/code> found in step 2a.\n        In this case, assign 1 to <code>x<\/code>.\n<\/ol>\n<p>\nThe modification to <code>x<\/code> that took place in <code>f<\/code>\nwas clobbered by the assignment operation that completed the\n<code>+=<\/code> sequence.\nAnd this behavior is not just in some weird\n&#8220;undefined behavior&#8221; corner of the language specification.\nThe language specification explicitly <i>requires<\/i> this behavior.\n<\/p>\n<p>\nNow, you might say,\n&#8220;Okay, I see your point, but this is clearly an unrealistic example,\nbecause nobody would write code this weird.&#8221;\n<\/p>\n<p>\nMaybe you don&#8217;t intentionally write code this weird, but you can\ndo it accidentally.\nAnd this is particularly true if you are using the new\n<code>await<\/code> keyword,\nbecause an <code>await<\/code> means,\n&#8220;Hey, like, put my function on hold and do other stuff for a while.\nWhen the thing I&#8217;m awaiting is ready,\nthen resume execution of my function.&#8221;\nAnd that &#8220;do other stuff for a while&#8221;\nmight change <code>x<\/code>.\n<\/p>\n<p>\nSuppose that you have a button in your application called <i>Buy More<\/i>.\nWhen the user clicks it, they can buy more widgets.\nLet&#8217;s assume that the <code>Buy&shy;More&shy;Async<\/code>\nfunction return the\nnumber of items bought. (If the user cancels the purchase\nit returns zero.)\n<\/p>\n<pre>\n\/\/ Suppose the user starts with 100 widgets.\nasync void BuyMoreButton_OnClick()\n{\n TotalWidgets += await BuyMoreAsync();\n Inventory.Text = string.Format(\"You have {0} widgets.\",\n                                TotalWidgets);\n}\nasync Task&lt;int&gt; BuyMoreAsync()\n{\n int quantity = QuickPurchase.IsChecked ? 1\n                                        : await GetQuantityAsync();\n if (quantity != 0) {\n  if (await DebitAccountAsync(quantity * PricePerWidget)) {\n   return quantity;\n  }\n }\n return 0; \/\/ user bought no items\n}\n<\/pre>\n<p>\nYou receive a bug report that you track back to the fact that\n<code>Total&shy;Widgets<\/code> does not match the\nnumber of widgets purchased.\nIt affects only people who checked the <i>quick purchase<\/i> box,\nand only people purchasing from overseas.\n<\/p>\n<p>\nHere&#8217;s what is going on.\n<\/p>\n<p>\nThe user clicks the <i>Buy More<\/i> button,\nand they have <i>Quick Purchase<\/i> enabled.\nThe <i>Buy&shy;More&shy;Async<\/i> function tries to\ndebit the account for the price of one widget.\n<\/p>\n<p>\nWhile waiting for the server to process the transaction,\nthe user gets impatient and clicks <i>Buy More<\/i> a second time.\nThis triggers a second task to debit the account for the\nprice of one widget.\n<\/p>\n<p>\nOkay, so you now have two tasks running,\neach processing one of the clicks.\nIn theory, the worst case is that the user accidentally\nbuys two widgets,\nbut in practice&#8230;\n<\/p>\n<p>\nThe first <code>Debit&shy;Account&shy;Async<\/code> task completes,\nand <code>Buy&shy;More&shy;Async<\/code> returns 1,\nwhich is then added to the value of\n<code>Total&shy;Widgets<\/code> at the time the button was clicked,\nas we discussed above.\nAt the time the button was clicked the first time, the number of\nwidgets was 100,\nso the total number of widgets is now 101.\n<\/p>\n<p>\nThe second <code>Debit&shy;Account&shy;Async<\/code> task completes,\nand <code>Buy&shy;More&shy;Async<\/code> returns 1,\nwhich is then added to the value of <code>Total&shy;Widgets<\/code>\nat the time the button was clicked,\nas we discussed above.\nWhen the button was clicked the second time,\nthe number of widgets was <i>still 100<\/i>.\nWe set the total widget count to <code>100 + 1 = 101<\/code>.\n<\/p>\n<p>\nResult: The user paid for two widgets but got only one.\n<\/p>\n<p>\nThe fix for this is to explicitly move waiting for the\npurchase to complete outside of the compound assignment.\n<\/p>\n<pre>\n int quantity = await BuyMoreAsync();\n TotalWidgets += quantity;\n<\/pre>\n<p>\nNow, the <code>await<\/code> is outside the compound assignment\nso that the value of <code>Total&shy;Widgets<\/code> is not captured\nprematurely.\nWhen the purchase completes, we update <code>Total&shy;Widgets<\/code>\nwithout interruption from any async operations.\n<\/p>\n<p>\n(You probably also should fix the program so it disables the\n<i>Buy More<\/i> button while a transaction is in progress,\nto avoid the <i>impatient user ends up making an accidental double\npurchase<\/i> problem. The above fix merely gets rid of the\n<i>user pays for two items and gets only one<\/i> problem.)\n<\/p>\n<p>\nLike\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/ericlippert\/archive\/2009\/11\/12\/closing-over-the-loop-variable-considered-harmful.aspx\">\nclosing around the loop control variable<\/a>,\nthis is the sort of subtle change that should be well-commented\nso that somebody doesn&#8217;t &#8220;fix&#8221; it in a well-intentioned but\nmisguided attempt to remove unnecessary variables.\nThe purpose of the variable is not to break an expression into two\nbut rather to force a particular order of evaluation:\nYou want to to finish the purchase operation before starting to\nupdate the widget count.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the C# language, operation\/assignment such as += are explicitly not atomic. But you already knew this, at least for properties. Recall that properties are syntactic sugar for method calls. A property declaration string Name { get { &#8230; } set { &#8230; } } is internally converted to the equivalent of string get_Name() { [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-243","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>In the C# language, operation\/assignment such as += are explicitly not atomic. But you already knew this, at least for properties. Recall that properties are syntactic sugar for method calls. A property declaration string Name { get { &#8230; } set { &#8230; } } is internally converted to the equivalent of string get_Name() { [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/243","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=243"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/243\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=243"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}