首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用TaskCompletionSource.SetResult实现线程安全

用TaskCompletionSource.SetResult实现线程安全
EN

Stack Overflow用户
提问于 2015-09-17 16:20:38
回答 1查看 2.1K关注 0票数 3

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

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

代码语言:javascript
复制
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);
    }
}

由于信息和字典对象是在一个线程上创建的,传递给另一个线程,并且在创建线程上不再被访问,所以似乎不需要执行任何锁定。对象永远不会被多个线程同时访问。

是否需要一个记忆屏障?

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-18 01:55:59

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

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

是否需要一个记忆屏障?

不是的。接收线程中的await将为您处理这个问题。

不过,我必须指出,Thread的使用听起来更像1990年的代码,而不是2015年的代码。你真的应该用Task.Run代替。而且由于Task.Run已经理解了结果类型,所以TaskCompletionSource<T>根本没用。哦,你应该避免async void

代码语言:javascript
复制
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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32635305

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档