C# 在.NET中返回数据的线程
我在写一个程序,通常从五个线程开始。螺纹以不确定的顺序返回。每个线程都在调用一个返回列表的方法 我正在这样做:C# 在.NET中返回数据的线程,c#,multithreading,C#,Multithreading,我在写一个程序,通常从五个线程开始。螺纹以不确定的顺序返回。每个线程都在调用一个返回列表的方法 我正在这样做: var masterList = List<string>(); foreach (var threadParam in threadParams) { var expression = threadParam ; ThreadStart sub = () => MyMethod(expressions); var thread = n
var masterList = List<string>();
foreach (var threadParam in threadParams)
{
var expression = threadParam ;
ThreadStart sub = () => MyMethod(expressions);
var thread = new Thread(sub)
{
Name = expression
};
listThreads.Add(thread);
thread.Start();
}
var abort = true;
while (abort) //Wait until all threads finish
{
var count = 0;
foreach (var list in listThreads)
{
if (!list.IsAlive)
{
count++;
}
}
if (count == listThreads.Count)
{
abort = false;
}
}
查看WaitHandle类和WaitHandle.WaitAll(我在一些代码中使用了ManualResetEvent类作为WaitHandle,但这只是一个示例。我不知道是否有更好的方法适合您的情况)。启动所有五个线程,给它们一个主列表的引用,在添加到主列表时锁定此列表,然后发出完成信号。使用WaitHandle.WaitAll阻塞,直到所有五个线程都发出完成信号。最好的方法是使每个线程都成为自己的对象。不要与其他对象混在一起,只需构造它(传递变量),将自己添加为侦听器并启动它 完成后,它将值存储在成员变量中,并通知您的侦听器 您的侦听器可以在空闲时检索这些值 显而易见的快捷方式是直接将值返回给侦听器,但您以后可能会发现这个版本更灵活(实际上没有更多的代码)使用
下面是一个例子:
using System;
using System.Threading;
class ThreadSleeper
{
int seconds;
AutoResetEvent napDone = new AutoResetEvent(false);
private ThreadSleeper(int seconds)
{
this.seconds = seconds;
}
public void Nap()
{
Console.WriteLine("Napping {0} seconds", seconds);
Thread.Sleep(seconds * 1000);
Console.WriteLine("{0} second nap finished", seconds);
napDone.Set();
}
public static WaitHandle DoSleep(int seconds)
{
ThreadSleeper ts = new ThreadSleeper(seconds);
Thread thread = new Thread(new ThreadStart(ts.Nap));
thread.Start();
return(ts.napDone);
}
}
public class OperationsThreadsWaitingwithWaitHandle
{
public static void Main()
{
WaitHandle[] waits = new WaitHandle[2];
waits[0] = ThreadSleeper.DoSleep(8);
waits[1] = ThreadSleeper.DoSleep(4);
Console.WriteLine("Waiting for threads to finish");
WaitHandle.WaitAll(waits);
Console.WriteLine("Threads finished");
}
}
查看链接:
sequential: 3224 ms
parallel: 2074 ms
当然,因为我没有构造显式线程,所以我把它留给线程池系统来计算并行运行的线程数
还提供了通过回调方法通知后台线程何时完成的规定,以及WaitHandle支持显式检查和等待超时等
资料来源:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Diagnostics;
namespace SO1215227
{
public class Program
{
public static void Main()
{
Stopwatch sw = new Stopwatch();
sw.Start();
var list1 = Sequence(1, 100);
var list2 = Sequence(101, 200);
var list3 = Sequence(201, 300);
sw.Stop();
Console.Out.WriteLine("sequential: " + sw.ElapsedMilliseconds + " ms");
sw.Reset();
Func<Int32, Int32, List<Int32>> listProducer = Sequence;
sw.Start();
var list1Background = listProducer.BeginInvoke(1, 100, null, null);
var list2Background = listProducer.BeginInvoke(101, 200, null, null);
var list3Background = listProducer.BeginInvoke(201, 300, null, null);
list1 = listProducer.EndInvoke(list1Background);
list2 = listProducer.EndInvoke(list2Background);
list3 = listProducer.EndInvoke(list3Background);
sw.Stop();
Console.Out.WriteLine("parallel: " + sw.ElapsedMilliseconds + " ms");
Console.Out.Write("Press enter to exit...");
Console.In.ReadLine();
}
private static List<Int32> Sequence(Int32 from, Int32 to)
{
List<Int32> result = new List<Int32>();
for (Int32 index = from; index <= to; index++)
{
result.Add(index);
Thread.Sleep(10); // simulate I/O wait
}
return result;
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统线程;
使用系统诊断;
名称空间SO1215227
{
公共课程
{
公共静态void Main()
{
秒表sw=新秒表();
sw.Start();
var list1=序列(1100);
var list2=序列(101200);
var list3=序列(201300);
sw.Stop();
控制台输出写入线(“顺序:+sw.ElapsedMilliseconds+“ms”);
sw.Reset();
Func listProducer=序列;
sw.Start();
var list1Background=listProducer.BeginInvoke(1100,null,null);
var list2Background=listProducer.BeginInvoke(101200,null,null);
var list3Background=listProducer.BeginInvoke(201300,null,null);
list1=listProducer.EndInvoke(list1Background);
list2=listProducer.EndInvoke(list2Background);
list3=listProducer.EndInvoke(list3Background);
sw.Stop();
Console.Out.WriteLine(“并行:+sw.elapsedmillyses+“ms”);
Console.Out.Write(“按enter键退出…”);
Console.In.ReadLine();
}
专用静态列表序列(Int32-from、Int32-to)
{
列表结果=新列表();
对于(Int32 index=from;索引与我的想法相同…但有一个更好的答案:(
using System;
using System.Collections.Generic;
using System.Threading;
using System.Diagnostics;
namespace SO1215227
{
public class Program
{
public static void Main()
{
Stopwatch sw = new Stopwatch();
sw.Start();
var list1 = Sequence(1, 100);
var list2 = Sequence(101, 200);
var list3 = Sequence(201, 300);
sw.Stop();
Console.Out.WriteLine("sequential: " + sw.ElapsedMilliseconds + " ms");
sw.Reset();
Func<Int32, Int32, List<Int32>> listProducer = Sequence;
sw.Start();
var list1Background = listProducer.BeginInvoke(1, 100, null, null);
var list2Background = listProducer.BeginInvoke(101, 200, null, null);
var list3Background = listProducer.BeginInvoke(201, 300, null, null);
list1 = listProducer.EndInvoke(list1Background);
list2 = listProducer.EndInvoke(list2Background);
list3 = listProducer.EndInvoke(list3Background);
sw.Stop();
Console.Out.WriteLine("parallel: " + sw.ElapsedMilliseconds + " ms");
Console.Out.Write("Press enter to exit...");
Console.In.ReadLine();
}
private static List<Int32> Sequence(Int32 from, Int32 to)
{
List<Int32> result = new List<Int32>();
for (Int32 index = from; index <= to; index++)
{
result.Add(index);
Thread.Sleep(10); // simulate I/O wait
}
return result;
}
}
}