Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.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_Locking - Fatal编程技术网

C# 枚举器中的多线程

C# 枚举器中的多线程,c#,multithreading,locking,C#,Multithreading,Locking,我使用的是C#,我有一个枚举器,我按顺序读取枚举器中的数据 这是第三方库对象,不支持Parallel.Foreach while(enumerator.Next()) { var item = enumerator.Read(); ProcessItem(item); } ProcessItem(Item item) { // Is lock required here if(item.prop == "somevalue") this._list.Add(item); }

我使用的是C#,我有一个枚举器,我按顺序读取枚举器中的数据

这是第三方库对象,不支持Parallel.Foreach

while(enumerator.Next())
{
  var item = enumerator.Read();
  ProcessItem(item);
}

ProcessItem(Item item)
{
// Is lock required here
 if(item.prop == "somevalue")
   this._list.Add(item);
}
我想在阅读内容时在这里实现多线程

while(enumerator.Next())
{
  // This code should run in a multi-threaded way

  var item = enumerator.Read();
  // ProcessItem method puts these items on a class level list property 
  // Is there any Lock required?
  ProcessItem(item);
}

我不熟悉多线程。请分享满足上述要求的所有代码示例。

这是基于任务的并行化的一个好例子。项目的每个处理对应于一个任务。因此,可以将循环更改为以下内容:

  var tasks = new List<Task<int>>();
  while(enumerator.MoveNext())
  {
    var item = enumerator.Current;

    Task<int> task = new Task<int>(() => ProcessItem(item));
    task.Start();
    tasks.Add(task);
  }


  foreach(Task<int> task in tasks)
  {
    int i = task.Result;
    classList.Add(i);
  }
var tasks=newlist();
while(枚举数.MoveNext())
{
变量项=枚举数。当前;
任务任务=新任务(()=>ProcessItem(item));
task.Start();
任务。添加(任务);
}
foreach(任务中的任务)
{
int i=任务。结果;
添加(i);
}

请注意,
classList
上的同步是通过首先在while循环中生成所有任务,然后在foreach循环中合并结果隐式实现的。同步是通过访问
结果
来实现的。

这是基于任务的并行化的一个很好的例子。项目的每个处理对应于一个任务。因此,可以将循环更改为以下内容:

  var tasks = new List<Task<int>>();
  while(enumerator.MoveNext())
  {
    var item = enumerator.Current;

    Task<int> task = new Task<int>(() => ProcessItem(item));
    task.Start();
    tasks.Add(task);
  }


  foreach(Task<int> task in tasks)
  {
    int i = task.Result;
    classList.Add(i);
  }
var tasks=newlist();
while(枚举数.MoveNext())
{
变量项=枚举数。当前;
任务任务=新任务(()=>ProcessItem(item));
task.Start();
任务。添加(任务);
}
foreach(任务中的任务)
{
int i=任务。结果;
添加(i);
}

请注意,
classList
上的同步是通过首先在while循环中生成所有任务,然后在foreach循环中合并结果隐式实现的。通过访问
结果
可以实现同步。

是的,需要一些锁定。您可以使用锁或并发集合类型来实现它

使用

ProcessItem(Item item)
{
    if(item.prop == "somevalue")
    {
        lock(_list)
        {
            _list.Add(item);
        }
    }
}
编辑:根据您提供的详细信息,您可以使用自己的枚举器从外部库包装
枚举器
,如下所示,这样您就可以在其上使用
Parallel.ForEach

我们假设您得到的枚举数类似于
MockEnumerator
,我们将其包装在一个普通的IEnumerator中,并且IEnumerable,因此我们可以使用
并行。ForEach
并行读取

class Program
{
    class Item
    {
        public int SomeProperty { get; }

        public Item(int prop)
        {
            SomeProperty = prop;
        }
    }

    class MockEnumerator
    {
        private Item[] _items = new Item[] { new Item(1), new Item(2) };
        private int _position = 0;

        public bool Next()
        {
            return _position++ < _items.Length;
        }

        public Item Read()
        {
            return _items[_position];
        }
    }

    class EnumeratorWrapper : IEnumerator<Item>, IEnumerable<Item>
    {
        private readonly MockEnumerator _enumerator;

        public EnumeratorWrapper(MockEnumerator enumerator)
        {
            this._enumerator = enumerator;
        }

        public Item Current => _enumerator.Read();

        object IEnumerator.Current => Current;

        public void Dispose()
        {
        }

        public IEnumerator<Item> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        public bool MoveNext()
        {
            return _enumerator.Next();
        }

        public void Reset()
        {
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this;
        }
    }

    private static List<Item> _list = new List<Item>();

    static void Main(string[] args)
    {
        var enumerator = new EnumeratorWrapper(new MockEnumerator());
        Parallel.ForEach(enumerator, item =>
        {
            if (item.SomeProperty == 1)//someval
            {
                lock (_list)
                {
                    _list.Add(item);
                }
            }
        });
    }
}
类程序
{
类项目
{
公共int SomeProperty{get;}
公共物品(整版道具)
{
SomeProperty=prop;
}
}
类枚举器
{
私有项[]_items=新项[]{新项(1)、新项(2)};
私有整数_位置=0;
公共图书馆下一页()
{
返回_position++<\u items.Length;
}
公共项目改为()
{
返回_项目[_位置];
}
}
类枚举器包装器:IEnumerator,IEnumerable
{
私有只读MockEnumerator_枚举器;
公共枚举器包装器(MockEnumerator枚举器)
{
此._枚举器=枚举器;
}
公共项当前=>\u枚举数.Read();
对象IEnumerator.Current=>Current;
公共空间处置()
{
}
公共IEnumerator GetEnumerator()
{
抛出新的NotImplementedException();
}
公共图书馆
{
返回_枚举数.Next();
}
公共无效重置()
{
}
IEnumerator IEnumerable.GetEnumerator()
{
归还这个;
}
}
私有静态列表_List=新列表();
静态void Main(字符串[]参数)
{
var enumerator=new EnumeratorWrapper(new MockEnumerator());
Parallel.ForEach(枚举器,项=>
{
如果(item.SomeProperty==1)//someval
{
锁定(_列表)
{
_列表。添加(项目);
}
}
});
}
}

是,需要一些锁定。您可以使用锁或并发集合类型来实现它

使用

ProcessItem(Item item)
{
    if(item.prop == "somevalue")
    {
        lock(_list)
        {
            _list.Add(item);
        }
    }
}
编辑:根据您提供的详细信息,您可以使用自己的枚举器从外部库包装
枚举器
,如下所示,这样您就可以在其上使用
Parallel.ForEach

我们假设您得到的枚举数类似于
MockEnumerator
,我们将其包装在一个普通的IEnumerator中,并且IEnumerable,因此我们可以使用
并行。ForEach
并行读取

class Program
{
    class Item
    {
        public int SomeProperty { get; }

        public Item(int prop)
        {
            SomeProperty = prop;
        }
    }

    class MockEnumerator
    {
        private Item[] _items = new Item[] { new Item(1), new Item(2) };
        private int _position = 0;

        public bool Next()
        {
            return _position++ < _items.Length;
        }

        public Item Read()
        {
            return _items[_position];
        }
    }

    class EnumeratorWrapper : IEnumerator<Item>, IEnumerable<Item>
    {
        private readonly MockEnumerator _enumerator;

        public EnumeratorWrapper(MockEnumerator enumerator)
        {
            this._enumerator = enumerator;
        }

        public Item Current => _enumerator.Read();

        object IEnumerator.Current => Current;

        public void Dispose()
        {
        }

        public IEnumerator<Item> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        public bool MoveNext()
        {
            return _enumerator.Next();
        }

        public void Reset()
        {
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this;
        }
    }

    private static List<Item> _list = new List<Item>();

    static void Main(string[] args)
    {
        var enumerator = new EnumeratorWrapper(new MockEnumerator());
        Parallel.ForEach(enumerator, item =>
        {
            if (item.SomeProperty == 1)//someval
            {
                lock (_list)
                {
                    _list.Add(item);
                }
            }
        });
    }
}
类程序
{
类项目
{
公共int SomeProperty{get;}
公共物品(整版道具)
{
SomeProperty=prop;
}
}
类枚举器
{
私有项[]_items=新项[]{新项(1)、新项(2)};
私有整数_位置=0;
公共图书馆下一页()
{
返回_position++<\u items.Length;
}
公共项目改为()
{
返回_项目[_位置];
}
}
类枚举器包装器:IEnumerator,IEnumerable
{
私有只读MockEnumerator_枚举器;
公共枚举器包装器(MockEnumerator枚举器)
{
此._枚举器=枚举器;
}
公共项当前=>\u枚举数.Read();
对象IEnumerator.Current=>Current;
公共空间处置()
{
}
公共IEnumerator GetEnumerator()
{
抛出新的NotImplementedException();
}
公共图书馆
{
返回_枚举数.Next();
}
公共无效重置()
{
}
IEnumerator IEnumerable.GetEnumerator()
{
归还这个;
}
}
私有静态列表_List=新列表();
静态void Main(字符串[]参数)
{
var enumerator=new EnumeratorWrapper(new MockEnumerator());
Parallel.ForEach(枚举器,项=>