【问题标题】:Threaded one-time variable assignment with multiple listeners in C# .NET在 C# .NET 中使用多个侦听器进行线程式一次性变量赋值
【发布时间】:2015-04-15 18:43:07
【问题描述】:

我有一个Variable 类型的类,它包含一个Value 类型的字段,该字段最初是未设置的(null),但将来会设置。多个线程可以访问一个Variable-object。带有签名Variable.Set(Value v) 的方法只被调用一次并设置变量。许多其他线程应该能够调用Variable.Wait() (在设置Variable 之前和之后) 其中:

  • 如果Variable 已设置,应立即返回。
  • 如果未设置Variable,则应(有效地)等待其设置,然后返回。

当我查看 API 时,我确信周围有一些明显的同步原语 - 监视器、事件、等待句柄或类似的 - 但我需要帮助找出最简单、最有效的解决方案,因为我正在学习并行性在 .NET 中。

【问题讨论】:

    标签: c# .net multithreading synchronization


    【解决方案1】:

    使用Lazy 类型允许通过一些长时间运行的工作来计算某些特定值,并让任意数量的线程等待该值,或者使用已经计算的值。

    【讨论】:

    • 我检查了 API,但不知道这对我有什么帮助? Variable 和 Value 在代码的不同部分初始化。 Variable.Set 方法将在 Variable 初始化后的某个时间点从其他地方调用。
    • @Betamos 然后使用TaskCompletionSource 设置Task<T>。
    • 谢谢! TaskCompletionSource 正是我所需要的。我将发布一个答案,解释我是如何做到的。
    【解决方案2】:

    感谢 Servy 的回答,我最终在 Variable 类中使用了私有 TaskCompletionSource<Value>。此外,我在整个应用程序中将async-await 模式与任务一起应用,所以我有一个Task<Value> Value() 字段,而不是Wait()-method,如下所示:

    class Variable
    {
        private TaskCompletionSource<Value> source;
        public Task<Value> Value
        {
            get;
            private set;
        }
    
        public Variable() // Constructor
        {
            taskSource = new TaskCompletionSource<Value>();
            Value = taskSource.Task;
        }
    
        public void Set(Value val) // Called exactly once
        {
            source.SetResult(val); // Triggers task completion
        }
    }
    

    【讨论】:

    • 这个类除了直接使用TaskCompletionSource之外没有添加任何东西。
    • 正确。我的课上还有很多其他的东西,为了便于阅读,我省略了。
    猜你喜欢
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    相关资源
    最近更新 更多