【问题标题】:Queue Task Threading队列任务线程
【发布时间】:2024-09-14 11:25:01
【问题描述】:

我有一种方法可以在每个路径中加载大量数据。

static void Execute()
{
    foreach (var path in paths)
    {
        loadData(path);
    }
}

private static Task _loadTask;
private static Dictionary<string, BarClass> _myDictionary = new Dictionary<string, BarClass>();

static void loadData()
{
      var myCollections = GetCollections.Collections;
     _loadTask = Task.Factory.StartNew((o) =>
     {
        foreach (var item in myCollections)
        {
             // Data Manipulation Goes Here
             ProcessConcat(_myDictionary, item.Value);
        }
     }, CancellationToken.None, TaskCreationOptions.LongRunning);
}

static void ProcessConcat(Dictionary<string, BarClass> _myDictionary, string key, BarClass value)
{
     if (!_myDictionary.ContainsKey(key))
          _myDictionary.Add(key, value)

}

问题是因为我使用集合,我总是得到一个异常。 现在我的问题是:如何实现队列和出队? :

我需要完成第一个data1的加载,然后在加载data1之后它会加载下一个Data ...

【问题讨论】:

  • 错误信息是什么?
  • 项目键已添加...空异常...集合已修改@P.K
  • “加载数据”是什么意思。你的意思是“从集合/字典中检索它”还是“首先第一个线程必须加载数据,主线程必须检索它,然后第二个线程可以加载第二个数据。”?
  • 你为什么要用字典?是否要通过键检索数据?
  • 您是否多次致电loadData

标签: c# winforms queue


【解决方案1】:

你也可以使用 ConcurrentDisctionary 来避免多线程中的问题

例子:

class Program
{
    static ConcurrentDictionary<string, int> _concurrent =
    new ConcurrentDictionary<string, int>();

    static void Main()
    {
    Thread thread1 = new Thread(new ThreadStart(A));
    Thread thread2 = new Thread(new ThreadStart(A));
    thread1.Start();
    thread2.Start();
    thread1.Join();
    thread2.Join();
    Console.WriteLine("Average: {0}", _concurrent.Values.Average());
    }

    static void A()
    {
    for (int i = 0; i < 1000; i++)
    {
        _concurrent.TryAdd(i.ToString(), i);
    }
    }
}

在以下位置查找示例源代码和文档:http://www.dotnetperls.com/concurrentdictionary


我不知道,但在你的代码中,为了避免错误,你需要使用锁来使收集线程安全,如下所示

private readonly Object lockobj = new Object();

static void ProcessConcat(Dictionary<string, BarClass> _myDictionary, string key, BarClass value)
{
    lock(lockobj)
    {
     if (!_myDictionary.ContainsKey(key))
          _myDictionary.Add(key, value)
    }
}

【讨论】:

    【解决方案2】:

    不使用字典,而是使用并发队列:https://msdn.microsoft.com/en-us/library/dd267265(v=vs.110).aspx

    此队列是线程安全的,您可以将已处理的项目推入并从另一个(主?)线程检索它。

    【讨论】: