TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Why I wish C# never got async/await

53 点作者 nullymcnull超过 10 年前

13 条评论

Strilanc超过 10 年前
Async&#x2F;await makes a lot of asynchronous code easier to write, which is great, but it amplifies some of the mistakes people were already making. The two examples in the post are:<p>- Developers won&#x27;t anticipate that accessing a task&#x27;s Result property can introduce a deadlock.<p>- Developers won&#x27;t anticipate race conditions due to a concurrent SynchronizationContext.<p>The problem from the first example actually does happen quite often. There are plenty of stackoverflow questions and blog posts about it. IMO there should be compiler warnings whenever you use Task.Result or Task.Wait. Actually I would prefer compile errors instead of just warnings, and for the implementations of Result and Wait to just be `throw new WHAT_IS_WRONG_WITH_YOU_DO_NOT_BLOCK_ON_TASKS_AAARGH_EXCEPTION()`, but that might be a bit harsh.<p>The problem from the second example is not really an issue with await&#x2F;async as opposed to a deeper language issue. Any concurrency mechanism in C# will be vulnerable to the fact that you can define and access shared mutable variables (including the solution proposed in the post).
评论 #8574990 未加载
Meai超过 10 年前
Yes, I agree. All async&#x2F;await seems to be is an abstraction around coroutines. Which is a little baffling, because coroutines are already a fairly standard way to solve this problem, so why introduce this weird async&#x2F;await syntax and pretend that it&#x27;s magic to solve &quot;concurrency&quot; in general.<p>I&#x27;m sure I just dont understand it, but hearing about leaky abstractions like he describes in the article just makes me that much more determined to never touch them. Too much magic, expertly hidden inside a closed .net runtime.
评论 #8574194 未加载
blkhp19超过 10 年前
I really like Grand Central Dispatch on iOS and OS X. You specify a task to run on a background queue or a main queue by passing a block of code. This block of code gets executed while the rest of the program continues. You can have completion blocks so you can respond to the completed task. The syntax is a little weird at first, but it&#x27;s pretty powerful and I find it to be very explicit. Async&#x2F;Await always confused me a bit.
评论 #8574799 未加载
Khao超过 10 年前
async&#x2F;await is there to reduce the massive amount of boilerplate code you need to write when doing async. Of course there will be corner case bugs or weird behaviors sometimes, but that doesn&#x27;t mean it&#x27;s all bad. If async&#x2F;await works for most cases, then it&#x27;s something that&#x27;s beneficial for a software developer like me.
评论 #8574230 未加载
skrebbel超过 10 年前
Having recently learned Elixir, I really wonder why the C# people decided to add async&#x2F;await rather than coroutines (like Erlang processes or Goroutines).<p>It feels to me like async&#x2F;await is the malloc of concurrent programming, and coroutines are the garbage collection of concurrent programming. You hand in a little performance in exchange for a <i>lot</i> less complexity. Go has shown you can also do this without only-immutable data.<p>Am I missing something?
评论 #8574688 未加载
评论 #8574970 未加载
ghodss超过 10 年前
&quot;By studying the output of the TraceThreadId method we see that in ASP.NET&#x2F;GUI it’s the same thread that enters ReadTask and that exits ReadTask ie no problems. When we run it as a Console application we see that ReadTask is entered by one thread and exited by another ie readingFiles is accessed by two separate threads with no synchronization primitives which mean we have a race-condition.&quot;<p>This is not entirely true - the code as written does not have a race condition because the two accesses are run sequentially. Accessing the same variable by two separate threads with no synchronization primitives is actually okay if those two threads never run in parallel. Now, if you called many ReadTask()&#x27;s in a row and you had thread_pool &gt; 1 (as in the GUI&#x2F;ASP.NET application), then you <i>would</i> have a race condition. But if you&#x27;re accessing a shared variable from a multithreaded context that should be somewhat obvious. It would depend on the programmer&#x27;s understanding of the async&#x2F;await paradigm, which I think is the author&#x27;s point. ;)
jasallen超过 10 年前
I continue to find using explicit &quot;Task&lt;T&gt;&quot; types directly more intuitive. I&#x27;ve wedged in ASync&#x2F;Await here and there to see if I felt good about it, but I never did. I would always find declaring a Task and attaching to it&#x27;s ContinueWith (or whatever I needed ) to be more to my liking.
评论 #8574693 未加载
评论 #8574283 未加载
评论 #8574272 未加载
zebracanevra超过 10 年前
The solution to deadlocking is using async all the way down - i.e. don&#x27;t use .Result. you can also tell C# not to resume on the same context after an async call by using .ConfigureAwait(false) on the tasks, thus preventing two locks on a context, and the deadlock.<p>The author states two threads accessing a single resource is a race-condition, but that&#x27;s only true when the threads are competing for that resource - in the case outlined in the article, it would be sequential, and only one thread would be accessing the resource at one time. No race condition.<p>I think it&#x27;s not too wise to think of async&#x2F;await as a special coroutine which never uses multiple threads, but as an easy way to write synchronous code and have it execute asyncronously. If you need fine control over what threads are used, maybe you&#x27;re better off controlling it manually.
blisse超过 10 年前
Is it really a problem that you have to be explicit in where you begin the top of the async&#x2F;await operation? You can&#x27;t just start the calls at a random point in code where you don&#x27;t understand the threading situation and expect to get consistent results.
youngthugger超过 10 年前
How does F# or C# async compare to GCD on Objective-C &#x2F; Swift ? Is it similar?
评论 #8575052 未加载
the_mitsuhiko超过 10 年前
The analogy to COM apartments is completely to the point. In fact, if you look at the PPL header files for C++&#x2F;CX you will notice that the PPL system explicitly refers to COM apartments. Since IAsyncAction and friends can be used from C++&#x2F;CX and .NET alike they are actually sharing very much of the same principles.
ziahamza超过 10 年前
C# already has basic support for computation expressions which they implemented to support LINQ and later extended for DLR, but I cant see why they couldnt extend it further for async tasks.
endeavour超过 10 年前
Just use F#
评论 #8574303 未加载