gpt4 book ai didi

c# - async 和 await 是否产生获取和释放语义?

转载 作者:行者123 更新时间:2023-12-02 00:21:44 27 4
gpt4 key购买 nike

关于从 async 方法返回是否总是产生释放语义以及 await 是否总是产生获取语义,我找不到明确的答案。我想是的,因为否则任何 async/await 代码都会成为雷区?

下面是一个示例:返回值是否保证为 100*212345*2,没有任何显式锁定或障碍?

private static async Task<(int, int)> AMethod()
{
// Runs on the original thread:
var x = 100;
var y = 12345;

var task = Task.Run(() =>
{
// Can run on another thread:
x *= 2;
y *= 2;

// Implicit return here, marking the task completed.
// Release semantics or not?
});

await task; // Acquire semantics or not?

// Runs on the original thread:
return (x, y);
}

编辑:当然,Task.Run 还需要生成一个版本,并且在开始运行任务代码时需要一个获取。忘记了原始问题中的那些。

最佳答案

是的,返回值都保证为 100*212345*2,没有任何明确的锁定或障碍。

在这种情况下,是 Task.Run 而不是 await 产生内存屏障。

引用wonderful Albahari Threading in C# :

The following implicitly generate full fences:

  • C#'s lock statement (Monitor.Enter/Monitor.Exit)
  • All methods on the Interlocked class (we’ll cover these soon)
  • Asynchronous callbacks that use the thread pool — these include asynchronous delegates, APM callbacks, and Task continuations
  • Setting and waiting on a signaling construct
  • Anything that relies on signaling, such as starting or waiting on a Task

By virtue of that last point, the following is thread-safe:

int x = 0;
Task t = Task.Factory.StartNew (() => x++);
t.Wait();
Console.WriteLine (x); // 1

Task.Run 包装 ThreadPool.UnsafeQueueUserWorkItem,属于“使用线程池的异步回调”。

参见 Memory barrier generators获取更全面的造成内存障碍的列表。

关于c# - async 和 await 是否产生获取和释放语义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55138674/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com