0

The method with signature static async Task is thread safety by default? In general, I assumed that the compiler might create some wrapper that provides "thread-safety". By the way, not on purpose.

Doesn't the compiler seeing 'static async' create something similar to what happens with java compilers and the 'synchronized' keyword?

Sorry for My English.

user1785960
  • 565
  • 5
  • 17
  • 2
    No and isn't even asynchronous by default. `async` is syntactic sugar that tells the compiler to create the state machine needed to *await* the execution of already active asynchronous operations. The code inside the method will be able to `await` asynchronous calls without blocking, and get back to the original synchronization context after they complete – Panagiotis Kanavos Aug 30 '23 at 07:44
  • Why this question? What's the actual problem you want to solve? `async/await` simplify writing thread-safe *asynchronous* code. That doesn't mean using multiple threads. In IO and network operations, the code is waiting for either the OS or a remote server to respond. `var text=await httpClient.GetStringAsync(url);` awaits for an HTTP response without blocking the current thread, and returns to the original synchronization context afterwards. In a desktop app that would be the UI thread, allowing you to update the UI right after the async call – Panagiotis Kanavos Aug 30 '23 at 07:47
  • @PanagiotisKanavos It was a question of pure curiosity. I didn't know how the compiler played around with async-await. – user1785960 Aug 30 '23 at 08:00
  • Why did you assume `async` would make a method thread-safe? It means you have a mental model of how it should work already. Did you expect it to work like JavaScript's `await` perhaps, which actually *starts* a method? Asynchronous doesn't mean parallel or concurrent. – Panagiotis Kanavos Aug 30 '23 at 08:09
  • 1
    No, the compiler does nothing like Java. The very names are opposites. `**sync**hronized` vs `**async*hronous`. Again, why the question? You're trying to fit `async/await` to an existing mental model that's simply wrong. Asynchronous programming isn't about threads and synchronization at all. The closest equivalent are callbacks executed after some action completes. – Panagiotis Kanavos Aug 30 '23 at 08:53
  • @PanagiotisKanavos: The situation with static async is more complicated. It's really a matter of what can handle the rest of the code after the 'await' keyword: https://stackoverflow.com/questions/69995931/need-some-explanations-about-async-await-and-thread-safety – user1785960 Aug 30 '23 at 09:30
  • 1
    My experience is that there are a number of people who see the Microsoft docs saying that all `static` method of class XXX are thread-safe and they assume it means all `static` methods of all classes are thread-safe. They are not. If it's in the documentation it's only there for those specific methods. It's not a general rule. – Enigmativity Aug 31 '23 at 09:12

1 Answers1

2

"Thread safety" is a vague and non-specific category of things; all that await (and all the associated bits) do[es] is setup the code to be suspendable and resumable via a state machine (although there is no guarantee that it will ever actually become truly async - it can run synchronously from start to finish); you need to be more specific

  • if you're asking about supporting concurrent invocation: that, just like any other code, depends on shared state (typically fields) and how you interact with them - we can't answer it from here
  • if you mean "do I come back on the same thread" (in terms of [ThreadStatic] etc): you should assume "no", but it might depending on sync-context (although that is an implementation detail of specific sync-context which may or may not be present)
  • if you mean "does my single method itself become self-concurrent" - if you await results immediately: no; if you don't: "possibly"
  • if you mean things like volatility, atomicity, etc: no more or less than any other code, although if you do jump threads the impact of these factors may be exacerbated - but the same concerns already existed
  • if you mean thread-bound locking (lock etc): don't ever use that with await

there are many other possible interpretations of "thread safety" - so: you'd need to be very specific

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • I suspect the OP confuses asynchronous and concurrent programming. – Panagiotis Kanavos Aug 30 '23 at 08:16
  • In general, I assumed that the compiler might create some wrapper that provides "thread-safety". – user1785960 Aug 30 '23 at 08:20
  • @user1785960 no, the compiler makes it easier to handle operation completions without callbacks. The `a` in async is a negation. `asynchronous` means `not synchronous` – Panagiotis Kanavos Aug 30 '23 at 08:57
  • @PanagiotisKanavos I see that the anwser depends on execution context: https://stackoverflow.com/questions/69995931/need-some-explanations-about-async-await-and-thread-safety – user1785960 Aug 30 '23 at 09:13
  • @user1785960 not quite. It's `await` that awaits for an active task to complete without blocking the original thread and returns execution to the original synchronization (not execution) context, after a Task completes. In a desktop application that means getting back to the UI thread. In a web application, where every request is served by a different threadpool thread, it means re-establishing the request context on a different thread. While awaiting, the original thread is free to perform other work – Panagiotis Kanavos Aug 30 '23 at 09:21
  • @PanagiotisKanavos: In some contexts, we are guaranteed that it will be one exactly the same thread. That's why it's thread-safe. – user1785960 Aug 30 '23 at 09:35
  • 1
    @user1785960 again, that comes down to definitions; define "thread safe" - what do you mean by that **exactly** - details matter; you say "same thread" - that is provided only by sync-contexts that *have that as a design feature*, which is *very rare* in modern frameworks, and is *not* an inherent feature of `await`, plus it depends exactly *what* you await; if I `await SomethingAsync().ConfigureAwait(false)`, then: that's gone again; sync-context is *not even remotely* like "synchronized", and attempting to compare them is not a good idea – Marc Gravell Aug 30 '23 at 10:03