gpt4 book ai didi

c# - TaskCompletionSource.SetResult 的线程安全

转载 作者:行者123 更新时间:2023-11-30 17:41:43 25 4
gpt4 key购买 nike

使用 TaskCompletionSource.SetResult() 将在一个线程上创建的非线程安全对象传递给另一个线程是否安全?

例如在这个人为的例子中:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;

public class Test
{
struct Info
{
public bool done;
public Dictionary<int, int> results;
}

public static void Main()
{
WaitForIt();
Console.ReadLine();
}

static async void WaitForIt()
{
TaskCompletionSource<Info> myTcs = new TaskCompletionSource<Info>();

Thread newThread = new Thread(new ParameterizedThreadStart(BackgroundThread));
newThread.Start(myTcs);

Info theInfo = await myTcs.Task;

Console.WriteLine(theInfo.done);
foreach (KeyValuePair<int, int> item in theInfo.results)
{
Console.WriteLine(item.Key + "=" + item.Value);
}
}

static void BackgroundThread(object tcs)
{
TaskCompletionSource<Info> theTcs = (TaskCompletionSource<Info>)tcs;

Info info = new Info();
info.done = true;
info.results = new Dictionary<int, int>();
info.results.Add(1, 2);
info.results.Add(3, 4);

theTcs.SetResult(info);
}
}

由于 Info 和 Dictionary 对象是在一个线程上创建的,然后传递给另一个线程,并且再也不会在创建线程上访问,因此似乎不需要执行任何锁定。这些对象永远不会被多个线程同时访问。

是否需要内存屏障?

是否保证读取线程与传递给 SetResult() 的创建线程具有完全相同的数据?

最佳答案

Is it safe to pass non-thread-safe objects created on one thread to another using TaskCompletionSource.SetResult()?

是的,只要该对象可以在与创建它的线程不同的线程上使用(当然)。

Is a memory barrier required?

没有。 await在接收线程中将为您处理。


不过,我必须指出,Thread 的使用读起来更像是 1990 年的代码,而不是 2015 年的代码。你真的应该使用 Task.Run反而。自 Task.Run已经了解结果类型,TaskCompletionSource<T> 没有用根本。哦,你应该避免 async void :

public static void Main()
{
WaitForItAsync().Wait();
Console.ReadLine();
}

static async Task WaitForItAsync()
{
Info theInfo = await Task.Run(() => CreateInfo());

Console.WriteLine(theInfo.done);
foreach (KeyValuePair<int, int> item in theInfo.results)
{
Console.WriteLine(item.Key + "=" + item.Value);
}
}

static Info CreateInfo()
{
Info info = new Info();
info.done = true;
info.results = new Dictionary<int, int>();
info.results.Add(1, 2);
info.results.Add(3, 4);
return info;
}

关于c# - TaskCompletionSource.SetResult 的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32635305/

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