Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# 使用线程-添加到集合 列表数据=新列表(); foreach(id中的int-id){ var myThread=新线程(新线程开始(工作)); myThread.Start(id); } 工作(){ }_C#_Multithreading - Fatal编程技术网

C# 使用线程-添加到集合 列表数据=新列表(); foreach(id中的int-id){ var myThread=新线程(新线程开始(工作)); myThread.Start(id); } 工作(){ }

C# 使用线程-添加到集合 列表数据=新列表(); foreach(id中的int-id){ var myThread=新线程(新线程开始(工作)); myThread.Start(id); } 工作(){ },c#,multithreading,C#,Multithreading,方法对接收到的id进行一些处理,然后将结果添加到数据列表中?如何从每个线程向集合添加数据?我的代码是什么样子的?谢谢,您可以从线程传递和检索数据(使用回调)。看 示例: List<int> data=new List<int>(); foreach(int id in ids){ var myThread=new Thread(new ThreadStart(Work)); myThread.Start(id); } Work(){ } 公共类Som

方法对接收到的id进行一些处理,然后将结果添加到数据列表中?如何从每个线程向集合添加数据?我的代码是什么样子的?谢谢,您可以从线程传递和检索数据(使用回调)。看

示例:

List<int> data=new List<int>();
foreach(int id in ids){
    var myThread=new Thread(new ThreadStart(Work));
    myThread.Start(id);
}


Work(){
}
公共类SomeClass
{
公共静态列表数据=新列表();
公共静态只读对象obj=新对象();
公共方法(int[]id)
{
foreach(id中的int-id)
{
工作w=新工作();
w、 数据=id;
w、 callback=ResultCallback;
var myThread=新线程(新线程开始(w.DoWork));
myThread.Start();
}
}
公共静态void ResultCallback(int d)
{        
锁(obj)
{        
数据.添加(d);
}
}
}
公共委托void ExampleCallback(int数据);
课堂作业
{
公共int数据{get;set;}
公共示例回调;
公共工作
{                
WriteLine(“实例线程过程.Data={0}”,Data);
if(回调!=null)
回调(数据);
}
}

您可以从线程传递和检索数据(使用回调)。看

示例:

List<int> data=new List<int>();
foreach(int id in ids){
    var myThread=new Thread(new ThreadStart(Work));
    myThread.Start(id);
}


Work(){
}
公共类SomeClass
{
公共静态列表数据=新列表();
公共静态只读对象obj=新对象();
公共方法(int[]id)
{
foreach(id中的int-id)
{
工作w=新工作();
w、 数据=id;
w、 callback=ResultCallback;
var myThread=新线程(新线程开始(w.DoWork));
myThread.Start();
}
}
公共静态void ResultCallback(int d)
{        
锁(obj)
{        
数据.添加(d);
}
}
}
公共委托void ExampleCallback(int数据);
课堂作业
{
公共int数据{get;set;}
公共示例回调;
公共工作
{                
WriteLine(“实例线程过程.Data={0}”,Data);
if(回调!=null)
回调(数据);
}
}

首先,您需要用锁保护多线程访问。其次,您需要将参数传递给线程(或者使用lambda,它可以捕获局部变量;注意,如果捕获循环变量,它将在循环期间更改值,因此您应该有一个局部副本)

objectcollectionlock=newobject();
列表数据=新列表();
foreach(id中的int-id)
{
螺纹t=新螺纹(工人);
t、 启动(id);
}
无效工作对象(对象o)
{
int id=(int)o;
锁(收集锁)
{
数据。添加(id);
}
}

首先,您需要用锁保护多线程访问。其次,您需要将参数传递给线程(或者使用lambda,它可以捕获局部变量;注意,如果捕获循环变量,它将在循环期间更改值,因此您应该有一个局部副本)

objectcollectionlock=newobject();
列表数据=新列表();
foreach(id中的int-id)
{
螺纹t=新螺纹(工人);
t、 启动(id);
}
无效工作对象(对象o)
{
int id=(int)o;
锁(收集锁)
{
数据。添加(id);
}
}

如果您使用的是.NET 4,我强烈建议您改用并行扩展。例如:

object collectionLock = new object();
List<int> data = new List<int>();

foreach (int id in ids)
{
    Thread t = new Thread(Worker);
    t.Start(id);
}

void Worker(object o)
{
    int id = (int)o;
    lock(collectionLock)
    {
        data.Add(id);
    }
}
其中
工作
为:

var list = ids.AsParallel()
              .Select(Work)
              .ToList();
这样它就可以适当地接收
id
。如果您不喜欢方法转换,可以添加lambda表达式:

public int Work(int id)
{
    ...
}

无论哪种方式,这都可以避免创建超出实际需要的线程,并且可以处理线程安全方面的问题,而无需您自己管理锁。

如果您使用的是.NET 4,我强烈建议您改用并行扩展。例如:

object collectionLock = new object();
List<int> data = new List<int>();

foreach (int id in ids)
{
    Thread t = new Thread(Worker);
    t.Start(id);
}

void Worker(object o)
{
    int id = (int)o;
    lock(collectionLock)
    {
        data.Add(id);
    }
}
其中
工作
为:

var list = ids.AsParallel()
              .Select(Work)
              .ToList();
这样它就可以适当地接收
id
。如果您不喜欢方法转换,可以添加lambda表达式:

public int Work(int id)
{
    ...
}

无论采用哪种方式,都可以避免创建超出实际需要的线程,并在不必自己管理锁的情况下处理线程安全方面的问题。

您需要手动管理锁定集合或使用.NET的一个并发集合。我建议将任务用于像这样简单的事情,不过,它巧妙地管理了线程造成的许多复杂性,并将引入一些非常有用的编程概念(如果你还不知道的话)。你肯定应该坚持他的方法。你需要手动锁定集合,或者使用.NET的一个并发集合。我建议将任务用于像这样简单的事情,不过,它巧妙地管理了线程造成的许多复杂性,并将引入一些非常有用的编程概念(如果你还不知道的话)。你绝对应该坚持他的方法。WRT:“你不能捕获循环变量”(它实际上可以被捕获——它总是同一个变量;-)来绕过这个问题。。。细节我使用
foreach(var x in…{var x=x;…}
,这很重要。@pst:是的,我的意思就是这个。捕获的变量在循环中被重用,因此捕获它并使用简单的方法会带来意外的行为。@pst:编辑答案以使其更清楚。谢谢你的建议