Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 已为字典线程问题添加密钥?_C#_.net_Dictionary_Thread Safety - Fatal编程技术网

C# 已为字典线程问题添加密钥?

C# 已为字典线程问题添加密钥?,c#,.net,dictionary,thread-safety,C#,.net,Dictionary,Thread Safety,我需要一些关于线程安全和字典的帮助。当添加到字典时,我会收到一个错误,上面写着“已经添加了具有相同键的项”(当我说我得到它时,我实际上无法复制它,但在错误日志中看到了它) 从我在阅读类似问题时看到的情况来看,这可能与线程安全有关,但我仍然不清楚发生了什么。由于很难测试,特别是当我无法复制它时,我希望有人能够解释或为我指明正确的方向。这是一个asp.net web应用程序(C#),在为特定用户定制测验时会发生错误。我尝试访问不存在的密钥时也会出错,但每次只能访问一个密钥 我举了一个小例子,把我认为

我需要一些关于线程安全和字典的帮助。当添加到字典时,我会收到一个错误,上面写着“已经添加了具有相同键的项”(当我说我得到它时,我实际上无法复制它,但在错误日志中看到了它)

从我在阅读类似问题时看到的情况来看,这可能与线程安全有关,但我仍然不清楚发生了什么。由于很难测试,特别是当我无法复制它时,我希望有人能够解释或为我指明正确的方向。这是一个asp.net web应用程序(C#),在为特定用户定制测验时会发生错误。我尝试访问不存在的密钥时也会出错,但每次只能访问一个密钥

我举了一个小例子,把我认为不必要的东西都去掉了,以说明问题。如果我脱得太多,请告诉我

public class QuizDataAdapterFactory
{
    private static IQuizDataAdapter q_adapter = new MyQuizDataAdapter();

    public static IQuizDataAdapter Create()
    {
        return q_adapter;
    }
}

IQuizDataAdapter dataAdapter = QuizDataAdapterFactory.Create();

public class MyQuizDataAdapter : IQuizDataAdapter
{
    private Quiz quiz;

    public Quiz GetQuiz()
    {
        quiz = new Quiz();
        quiz.QuestionIndex = new Dictionary<Guid, QuestionBase>();

        GetQuestions();

        return quiz;
    }

    private void GetQuestions()
    {
        Item[] items;

        foreach (Item questionItem in items)
        {
            Question newQuestion = new Question();
            PopulateQuestionFromItem(newQuestion, questionItem);
            questions.Add(newQuestion);

            // this is where it fails
            quiz.QuestionIndex.Add(questionItem.ID.ToGuid(), newQuestion);
        }
    }
}
公共类QuizDataAdapterFactory
{
私有静态IQuizDataAdapter q_adapter=new MyQuizDataAdapter();
公共静态IQuizDataAdapter创建()
{
返回q_适配器;
}
}
IQuizDataAdapter=QuizDataAdapterFactory.Create();
公共类MyQuizDataAdapter:IQuizDataAdapter
{
私人问答游戏;
公共小测验
{
测验=新测验();
quick.QuestionIndex=新字典();
获取问题();
回访测验;
}
私人问题
{
项目[]项目;
foreach(项目问题项目中的项目)
{
问题newQuestion=新问题();
PopulateQuestionFromItem(newQuestion,questionItem);
问题。添加(新问题);
//这就是它失败的地方
quick.QuestionIndex.Add(questionItem.ID.ToGuid(),newQuestion);
}
}
}
为IQuizDataAdapter添加
[ThreadStatic]
会起作用吗

谢谢

Annelie

由于您的
Create
方法的命名完全不恰当,您只创建了一个
MyQuizDataAdapter
实例-它不会“创建”适配器,每次都返回相同的一个


相反,每次创建一个不同的,你至少会处于一个更好的位置。。。诚然,我不太喜欢每次调用
getquick
时,它也会在
MyQuizDataAdapter
中重新填充测验,但这是另一个步骤……

这段代码是由多个线程访问的吗?@Tony-不,只是一个普通页面。哇,我很荣幸从强大的Skeet中得到了答案!:)我正在修改它以创建一个不同的工厂,我也刚刚与编写代码的开发人员进行了交谈,他说我也可以摆脱工厂,因为它现在什么都不做。谢谢至于getquick,也许我已经去掉了太多的代码来理解它(如果不是的话,任何重构建议都是最受欢迎的!)。GetQuike将quizID作为参数,然后转到Sitecore并在生成测验之前获取正确的测验项目。@annelie:在这种情况下,我想知道问题是否真的是您正在“存储”您正在创建的测验。为什么GetQuestions在MyQuizDataAdapter中而不是在测验中?如果它真的在MyQuizDataAdapter中,它应该只返回问题,而不是将它们添加到测验中。基本上,就我所能看到的而言,信息被存储得太广了。@Jon Skeet-我认为GetQuestions确实属于MyQuizDataAdapter,但也许问题索引不是一个好主意?根据他在quick.cs中的评论,这本词典是为了“保存所有问题的索引,这样你就不必每次都遍历这棵树”。也许我应该把它移走?@annelie:在测验中这样做听起来很合理,但数据适配器应该只返回问题,让测验自己添加问题,我想。