首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#更新不同类中的字典

C#更新不同类中的字典
EN

Stack Overflow用户
提问于 2016-03-14 21:01:29
回答 2查看 605关注 0票数 0

我有一本包含数据的字典,还有处理并发客户端请求的线程。我希望一些客户端请求在需要时更改字典中的值,但不确定在处理线程和类时如何修复范围问题。

下面是我想要做的一个简单的例子:

代码语言:javascript
运行
复制
class Program 
{
    public static Dictionary<string, int> teamInformation = new Dictionary<string, int>();

static void Main(string[] args)
{
    runserver();
}

static void runServer()
{
    //connection stuff

    while(true)
    {
        threadRequest = new Handler();
        Thread t = new Thread (() => threadRequest.clientInteraction(connection));
        t.Start();
    }
}

class Handler
{
    public void clientInteraction(Socket connection)
    {
        //does stuff

        teamInformation.Add(pTeamName, 0); //where pTeamName has been read from the client input
    }
}

我将如何修改Handler类中的字典(它需要所有线程都可以访问)?

我不知道如何在字典条目中索引线程,或者至少标记它们。我很难找到将特定值发送到特定线程的方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-14 21:31:03

从.NET 4.0开始,集合对线程安全有更好的处理。您可以让许多线程在没有问题的情况下写入它们。(https://msdn.microsoft.com/en-us/library/dd997305(v=vs.110).aspx.同样的情况也适用于多个读者。

问题在于,当两个操作同时发生时,通过被修改的集合进行枚举是一个问题。

更好的选择是使用支持线程安全的数据类型,例如ConcurrentDictionary,它是线程安全的,同时允许读取器和写入器。(不包括通过ConcurrentDictionary实现的接口访问的一些成员)。

对于您来说,这种更改很可能是从:public static Dictionary<string, int> teamInformation = new Dictionary<string, int>();public static ConcurrentDictionary<string, int> teamInformation = new ConcurrentDictionary<string, int>();的一种下降。

请参阅https://msdn.microsoft.com/en-us/library/dd287191(v=vs.110).aspx以获得更大的深度

编辑:下面是它的用法的一个例子:

代码语言:javascript
运行
复制
using System;
using System.Collections.Concurrent;
using System.Threading;

namespace SO
{
    public class Program
    {
        public static ConcurrentDictionary<string, int> teamInformation = new ConcurrentDictionary<string, int>();

        static void Main(string[] args)
        {
            Start();

            Console.WriteLine("ConcurrentDictionary contains : " + teamInformation.Count);
            Console.ReadKey();
        }

        static void Start()
        {
            for (var i = 0; i < 10; i++)
            {
                var threadRequest = new Handler();
                var thread = new Thread(() => threadRequest.ClientInteraction(teamInformation));
                thread.Start();
            }
        }
    }

    public class Handler
    {
        public void ClientInteraction(ConcurrentDictionary<string, int> teamInformation)
        {
            for (var i = 0; i < 10; i++)
            {
                teamInformation.AddOrUpdate(Guid.NewGuid().ToString(), i, (key, val) => val);
            }
        }
    }
}

由于ConcurrentDictionary是线程安全的,所以您可以直接将它传递给线程。这段代码只是生成一个线程负载,并为每个线程创建一个新条目。

但是,通过使用AddOrUpdate,您可以指定如果存在密钥(或团队),可以使用第三个Func更新现有条目。

共享该属性的其他选项将通过静态类或单例进行。您可能需要考虑将使用此属性的是什么,以及当前的体系结构,以查看将其放入何处。

票数 2
EN

Stack Overflow用户

发布于 2016-03-14 21:10:16

您可以将字典作为参数放在start函数中,如下所示:

代码语言:javascript
运行
复制
Thread t = new Thread (() => threadRequest.clientInteraction(connection));
    t.Start(ref teamInformation);

https://msdn.microsoft.com/en-us/library/6x4c42hc%28v=vs.110%29.aspx

重要的是通过引用使用调用,这样您就可以访问相同的字典而不是副本。但是我不确定编译器是否会接受这里的“ref”

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35997994

复制
相关文章

相似问题

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