【问题标题】:key already added for dictionary - thread problem?已为字典添加键 - 线程问题?
【发布时间】:2011-07-01 10:04:00
【问题描述】:

我需要一些帮助来了解线程安全和字典。添加到字典时,我收到一条错误消息,提示“已添加具有相同键的项目”(当我说我得到它时,我实际上无法复制它,但在错误日志中看到它)。

从我在阅读类似问题时看到的情况来看,这可能与线程安全有关,但我仍然不清楚发生了什么。而且由于很难测试,尤其是当我无法复制它时,我希望有人能够解释或指出我正确的方向。这是一个 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);
        }
    }
}

为 IQuizDataAdapter 添加[ThreadStatic] 会起作用吗?

谢谢,

安妮莉

【问题讨论】:

  • 这段代码是否被多个线程访问?
  • @Tony - 不,只是一个普通页面。

标签: c# .net dictionary thread-safety


【解决方案1】:

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

每次都创建一个不同的,至少你会处于一个更好的位置......诚然,我不太喜欢每次你打电话给GetQuiz它重新填充MyQuizDataAdapter中的测验的方式也是,但那是另一个步骤...

【讨论】:

  • 哇,我很荣幸能从强大的 Skeet 那里得到答案! :) 我正在更改它以创建一个不同的,我也刚刚与编写代码的开发人员聊天,他说我也可以摆脱工厂,因为它现在什么都不做。谢谢!
  • 至于 GetQuiz,也许我已经删除了太多代码来理解这一点(如果没有任何重构建议,欢迎!)。 GetQuiz 将 quizID 作为参数,然后转到 Sitecore 并在构建测验之​​前获取正确的测验项目。
  • @annelie:在这种情况下,我想知道问题是否真的在于您正在“存储”您正在创建的测验。为什么 GetQuestions 在 MyQuizDataAdapter 中而不是在 Quiz 中?如果它真的应该在 MyQuizDataAdapter 中,它应该只返回问题,而不是将它们添加到测验中。就我所见,基本上信息存储得太广泛了。
  • @Jon Skeet - 我认为 GetQuestions 确实属于 MyQuizDataAdapter,但也许问题索引不是一个好主意?根据他在 Quiz.cs 中的评论,创建字典是为了“保存所有问题的索引,这样你就不需要每次都遍历树”。也许我应该移动它?
  • @annelie:在测验中听起来很合理——但是数据适配器应该返回问题,并让测验自己添加问题,IMO。
猜你喜欢
  • 2019-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-09
  • 2013-02-16
  • 2016-02-09
  • 1970-01-01
相关资源
最近更新 更多