锁定Dictionary-Entry vs ConcurrentDictionary

时间:2014-10-18 21:14:48

标签: c# dictionary

我试图完成以下工作:我得到一个降价文本,需要改变每个规则,例如: # - > h1,* *表示斜体等。

这是一场比赛,表演是其中一个要点。

所以我的方法很简单:我分割线条,然后为每个规则创建字典并为每个规则开始一个任务,这样它们就可以并行工作:

    private Dictionary<Rule, Dictionary<int, string>> SplitLinesByRule()
    {
        var result = new Dictionary<Rule, Dictionary<int, string>>();
        Dictionary<int, string> tmpLines;

        tmpLines = _formattedLines.Where(f => string.IsNullOrEmpty(f.Value)).ToDictionary(f => f.Key, f => f.Value);
        result.Add(Rule.Block, tmpLines);

        tmpLines = _formattedLines.Where(f => f.Value.StartsWith("*")).ToDictionary(f => f.Key, f => f.Value);
        result.Add(Rule.Enumeration, tmpLines);

        tmpLines = _formattedLines.Where(f => f.Value.Count(ff => ff == '*') > 1).ToDictionary(f => f.Key, f => f.Value);
        result.Add(Rule.Cursive, tmpLines);

        tmpLines = _formattedLines.Where(f => f.Value.StartsExactlyWith("~~~~")).ToDictionary(f => f.Key, f => f.Value);
        result.Add(Rule.Code, tmpLines);

        tmpLines = _formattedLines.Where(f => f.Value.StartsExactlyWith("####")).ToDictionary(f => f.Key, f => f.Value);
        result.Add(Rule.Headline4, tmpLines);

        tmpLines = _formattedLines.Where(f => f.Value.Length >= 3 && f.Value.StartsExactlyWith("###")).ToDictionary(f => f.Key, f => f.Value);
        result.Add(Rule.Headline3, tmpLines);

        tmpLines = _formattedLines.Where(f => f.Value.Length >= 2 && f.Value.StartsExactlyWith("##")).ToDictionary(f => f.Key, f => f.Value);
        result.Add(Rule.Headline2, tmpLines);

        tmpLines = _formattedLines.Where(f => f.Value.Length >= 1 && f.Value.StartsExactlyWith("#")).ToDictionary(f => f.Key, f => f.Value);
        result.Add(Rule.Headline1, tmpLines);

        tmpLines = _formattedLines.Except(result.SelectMany(f => f.Value)).ToDictionary(f => f.Key, f => f.Value);
        result.Add(Rule.None, tmpLines);

        return result;
    } 

其次是:

        Task[] tasks = new Task[]
        {
            Task.Factory.StartNew(() =>
            {
                HandleBlocks(lineChunks.First(f => f.Key == Rule.Block).Value);
            }),

            Task.Factory.StartNew(() =>
            {
                HandleCode(lineChunks.First(f => f.Key == Rule.Code).Value);
            }),

            Task.Factory.StartNew(() =>
            {
                HandleCursive(lineChunks.First(f => f.Key == Rule.Cursive).Value);
            }),

            Task.Factory.StartNew(() =>
            {
                HandleEnumeration(lineChunks.First(f => f.Key == Rule.Enumeration).Value);
            }),

            Task.Factory.StartNew(() =>
            {
                HandleH1(lineChunks.First(f => f.Key == Rule.Headline1).Value);
            }),

            Task.Factory.StartNew(() =>
            {
                HandleH2(lineChunks.First(f => f.Key == Rule.Headline2).Value);
            }),

            Task.Factory.StartNew(() =>
            {
                HandleH3(lineChunks.First(f => f.Key == Rule.Headline3).Value);
            }),

            Task.Factory.StartNew(() =>
            {
                HandleH4(lineChunks.First(f => f.Key == Rule.Headline4).Value);
            }),

            Task.Factory.StartNew(() =>
            {
                HandleNoneRule(lineChunks.First(f => f.Key == Rule.None).Value);
            })
        };

        Task.WaitAll(tasks);

我的问题是:一行可以有多个规则,所以我的第一个方法是ConcurrentDictionary并添加Lines,它们无法更新到posion队列并单独处理它们:

    private void TryUpdate(KeyValuePair<int, string> line, string newValue)
    {
        bool ok = _formattedLines.TryUpdate(line.Key, newValue, line.Value);
        if (!ok) _poisonQueue.Add(line.Key, line.Value);
    }

我想这会起作用,但是性能不会那么好,而且检查每条线路都会变得非常复杂,这对于规则来说也是行不通的。

另一种方法是创建一个普通的Dictionary并基本上锁定它更新的行,这样可能会有多行被更新,但只有同一行一次(不是工作示例):

    private void TryUpdate(KeyValuePair<int, string> line, string newValue)
    {
        lock (line.Key as object)
        { 
            _formattedLines[line.Key] = newValue;
        }
    }

问题当然是,只有最后一条规则会更新,所以我需要在这里做其他事情。

还有其他方法我没有照顾吗?是否有另一种方法比试图为自己处理每条规则更有效率?

0 个答案:

没有答案