Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.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#_Multithreading_Asynchronous_Async Await_Task Parallel Library - Fatal编程技术网

C# 实现并发操作的最佳方法

C# 实现并发操作的最佳方法,c#,multithreading,asynchronous,async-await,task-parallel-library,C#,Multithreading,Asynchronous,Async Await,Task Parallel Library,我有两个包含不同长度字符串的列表。我需要使用一个算法(比如AlgorithmX)来比较这两个列表,该算法将确定是否应该保留ListA中的字符串。列表很长(每个列表超过50000个项目),长度从1个字符到5000个字符不等 因此,我们至少要进行50000*50000次比较(不是直接比较,列表中的每个字符串都要经过AlgorthmX) 现在我对多线程的知识还不多。但我一直在阅读它。然而在.Net中有各种各样的实现。标准线程、任务、等待异步 使用AlgorithmX和多线程进行列表比较的最佳方法是什么

我有两个包含不同长度字符串的列表。我需要使用一个算法(比如AlgorithmX)来比较这两个列表,该算法将确定是否应该保留ListA中的字符串。列表很长(每个列表超过50000个项目),长度从1个字符到5000个字符不等

因此,我们至少要进行50000*50000次比较(不是直接比较,列表中的每个字符串都要经过AlgorthmX)

现在我对多线程的知识还不多。但我一直在阅读它。然而在.Net中有各种各样的实现。标准线程、任务、等待异步

使用AlgorithmX和多线程进行列表比较的最佳方法是什么?也就是说,我应该使用await async任务库吗

我是否应该在每个CPU上平均分割ListA的项目,并针对ListB运行算法?我是否应该在分割列表上使用concurrentQueue

[编辑] ConcurrentQueue似乎是我要找的……但欢迎添加任何内容


欢迎使用任何指针!

这是一种可能的实现,它使用
ConcurrentQueue
存储算法决定保留的字符串(注意:没有特别的理由不使用其他线程安全集合)

此方法用于迭代
列表a

private static void Main()
{
    var listA = new[] {"the", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"};
    var listB = new List<string>(new[] {"fox", "dog", "cat", "mouse"});
    var stringsToKeep = new ConcurrentQueue<string>();

    Parallel.ForEach(listA, a =>
    {
        var shouldKeep = AlgorithmX(a, listB);
        if (shouldKeep)
        {
            stringsToKeep.Enqueue(a);
        }
    });

    Console.WriteLine($"Matching strings: {string.Join(", ", stringsToKeep.ToArray())}");
}
private static void Main()
{
var listA=new[]{“the”,“quick”,“brown”,“fox”,“jumped”,“over”,“the”,“lazy”,“dog”};
var listB=新列表(新[]{“狐狸”、“狗”、“猫”、“老鼠”});
var stringstokep=新的ConcurrentQueue();
Parallel.ForEach(listA,a=>
{
var shouldKeep=AlgorithmX(a,listB);
如果(应该保持)
{
列队(a);
}
});
WriteLine($”匹配字符串:{string.Join(“,”,stringsToKeep.ToArray())});
}
假设:

  • 在进行比较时,不需要修改
    ListA
    ListB
    。只要不修改它们,就不会出现并发访问问题(在多线程环境中,对
    列表的只读访问是可以的-只有当列表被修改时才会出现并发问题-例如插入/删除/等等)
  • AlgorithmX
    没有副作用(即,该方法是“纯”的,因此线程安全的-能够在没有问题的情况下并发调用)
  • ListA
    中的字符串顺序不需要反映在结果中(即,您不关心算法决定保留的字符串顺序)
  • 然而,在.Net中有多种[multithreading]实现。标准线程、任务、等待异步

    使用AlgorithmX和多线程进行列表比较的最佳方法是什么?也就是说,我应该使用await async任务库吗

    如果您后退一步,您会发现
    async
    /
    await
    在这里不合适。“并发性”一次做不止一件事。异步是一种不使用专用线程进行操作的并发形式,您可以将其视为更基于事件的并发形式。并行是一种使用多个线程进行操作的并发形式。异步和并行都是并发形式,但在出现时是相反的因此,异步通常用于I/O绑定或其他与CPU无关的任务,如计时器;并行通常用于CPU工作,如运行一百万次计算算法

    关于并行性,通常来说,最好使用具有最高抽象的工具。手动线程是正确的,就像直接使用线程池一样

    在您的例子中,您希望使用
    Parallel
    或Parallel LINQ,两者都构建在任务并行库之上,而任务并行库又使用线程池

    有一个问题,但我发现,如果您需要一个操作的结果,并行LINQ通常会产生更简单的代码。在这种情况下:

    static List<string> RunAlgorithm(List<string> listA, List<string> listB)
    {
      return listA.AsParallel()
          .Where(a => AlgorithmX(a, listB)).ToList();
    }
    

    AlgorithmX只是一个交集还是更复杂的东西?所以你既不修改ListA也不修改ListB?你想使用ConcurrentQueue来存储要保留的字符串的结果?这也是我的第一种方法。分区可能有意义。很难说。最后它需要试验真实数据和真实算法,
    static List<string> RunAlgorithm(List<string> listA, List<string> listB)
    {
      return listA.AsParallel().AsOrdered()
          .Where(a => AlgorithmX(a, listB)).ToList();
    }