【问题标题】:How to store a Channel in a Concurrent Dictionary如何在并发字典中存储通道
【发布时间】:2021-02-12 07:14:24
【问题描述】:

这里是一个相当棘手的问题,但我试图理解的概念相当简单。

我有一个公共静态并发字典,可以从其他类和线程访问:

public static readonly ConcurrentDictionary<int, object> tcpServerChannelDictionary = new ConcurrentDictionary<int, object>();

我有一个特定的后台线程,我最初在其中创建了一个新的 C# 通道并将实例存储在字典中。在同一个线程中(在同一个方法中),我开始异步等待消息。从方法中删除了一些不必要的代码膨胀:

var myChannel = Channel.CreateUnbounded<string>();
            tcpServerChannelDictionary.TryAdd(int, myChannel);

await foreach (var data in myChannel.Reader.ReadAllAsync())
{
    // Do something with message
}

第一个绊脚石是我无法将静态字典定义为“对象”作为通道,即 ConcurrentDictionary... 因为我会收到警告信号“通道:无法使用静态类型”作为类型参数”,所以这就是我声明对象类型的原因。

这似乎在没有 VS 代码警告的情况下工作,直到我尝试从另一个类(以及另一个线程)访问字典对象:

if (TcpServer.tcpServerChannelDictionary.TryGetValue(int, out Channel myChannel))
{
   await myChannel.Writer.WriteAsync(data);
}

不知何故,我需要将对象投射到我尝试访问的通道,以便我可以向它写入消息,或者其他一些防止警告的解决方案。我刚接触频道,但立即看到使用它们会有多么强大。

【问题讨论】:

  • Channel 是一个辅助静态类。在这种情况下,该方法返回一个 Channel,其中 T=string。你可以把这些放在你的字典里

标签: c# system.threading.channels


【解决方案1】:

Channel 类是一个带有工厂方法的辅助静态类。所有这些方法都返回一个Channel&lt;T&gt;。在您的情况下,您正在创建 Channel&lt;string&gt; 对象,这是可以构造 Dictionary 的类型。

public static readonly ConcurrentDictionary<int, Channel<string>> tcpServerChannelDictionary = new();
//... 
if (TcpServer.tcpServerChannelDictionary.TryGetValue(int, out var /*Channel<string>*/ myChannel)) 
{
   await myChannel.Writer.WriteAsync(data);
}

现在,如果出于某种原因您仍需要为字典的值使用 object 类型(也许您对 Channel&lt;T&gt; 有不同的通用参数并且您希望它们都在同一个集合中)您的 out 变量仍然需要object 然后你需要转换它:

if (TcpServer.tcpServerChannelDictionary.TryGetValue(int, out var /*object*/ oChannel) && oChannel is Channel<string> myChannel)
{
   await myChannel.Writer.WriteAsync(data);
}

【讨论】:

  • 哈哈,这不是我问过的最聪明的问题,现在看到问题出在哪里了,第二双眼睛总是能帮助疲惫的眼睛……谢谢老兄。
猜你喜欢
  • 1970-01-01
  • 2019-09-20
  • 2021-04-06
  • 2019-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-06
  • 2020-06-14
相关资源
最近更新 更多