Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# async和await是否产生acquire和release语义?_C#_.net_Async Await_Language Lawyer_Memory Model - Fatal编程技术网

C# async和await是否产生acquire和release语义?

C# async和await是否产生acquire和release语义?,c#,.net,async-await,language-lawyer,memory-model,C#,.net,Async Await,Language Lawyer,Memory Model,对于从async方法返回是否总是产生发布语义,以及wait是否总是产生获取语义,我找不到明确的答案。我假设是的,因为否则任何async/await代码都会是雷区 下面是一个例子:返回值是否保证都是100*2和12345*2,没有任何明确的锁或障碍 private static async Task<(int, int)> AMethod() { // Runs on the original thread: var x = 100; var y = 12345

对于从
async
方法返回是否总是产生发布语义,以及
wait
是否总是产生获取语义,我找不到明确的答案。我假设是的,因为否则任何
async/await
代码都会是雷区

下面是一个例子:返回值是否保证都是
100*2
12345*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);
}
private静态异步任务AMethod()
{
//在原始线程上运行:
var x=100;
变量y=12345;
var task=task.Run(()=>
{
//可以在其他线程上运行:
x*=2;
y*=2;
//此处隐式返回,标记任务已完成。
//是否释放语义?
});
等待任务;//是否获取语义?
//在原始线程上运行:
返回(x,y);
}

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

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

在这种情况下,产生内存障碍的是
任务.Run
,而不是
wait

引述:

以下命令隐式生成完整的围栏:

  • C#的锁语句(Monitor.Enter/Monitor.Exit)
  • 联锁类上的所有方法(我们将很快介绍这些)
  • 使用线程池的异步回调-包括异步委托、APM回调和任务延续
  • 设置和等待信令构造
  • 任何依赖于信号的东西,如开始或等待任务
根据最后一点,以下是线程安全的:

int x = 0;
Task t = Task.Factory.StartNew (() => x++);
t.Wait();
Console.WriteLine (x);    // 1
Task.Run
包装
ThreadPool.UnsafeQueueUserWorkItem
,它属于“使用线程池的异步回调”


有关创建内存障碍的内容的更全面列表,请参阅。

添加
wait任务。配置wait(false)
。然后你肯定不能保证x和y将是
100*2
12345*2
@YauhenSampir否,这对问题没有任何影响。相关:@YauhenSampir如果发布和获取都存在,无论
如何,你仍然会得到一个好结果。ConfigureAwait(false)
。当然,获取和释放也是开始任务所必需的,而不仅仅是完成任务。嗯。谢谢你提到那件事。将编辑问题。