class MultiThreading
{
public class ThreadClass
{
public string InputString { get; private set; }
public int StartPos { get; private set; }
public List<SearchAlgorithm.CandidateStr> completeModels;
public List<SearchAlgorithm.CandidateStr> partialModels;
public ThreadClass(string s, int sPos)
{
InputString = s;
StartPos = sPos;
completeModels = new List<SearchAlgorithm.CandidateStr>();
partialModels = new List<SearchAlgorithm.CandidateStr>();
}
public void Run(int strandID)
{
Thread t = new Thread(() => this._run(strandID));
t.Start();
}
private void _run(int strandID)
{
SearchAlgorithm.SearchInOneDirection(strandID, ref this.completeModels, ref this.partialModels);
}
public static void CombineResult(
List<ThreadClass> tc,
out List<SearchAlgorithm.CandidateStr> combinedCompleteModels,
out List<SearchAlgorithm.CandidateStr> combinedPartialModels)
{
// combine the result
}
}
}
class Program
{
static void Main(string s, int strandID)
{
int lenCutoff = 10000;
if (s.Length > lenCutoff)
{
var threads = new List<MultiThreading.ThreadClass>();
for (int i = 0; i <= s.Length; i += lenCutoff)
{
threads.Add(new MultiThreading.ThreadClass(s.Substring(i, lenCutoff), i));
threads[threads.Count - 1].Run(strandID);
}
**// How can I wait till all thread in threads list to finish?**
}
}
}
我的问题是我怎么能等到“线程”列表中的所有线程完成然后再调用CombineResult方法?
由于
答案 0 :(得分:5)
您可以添加List<Thread>
结构来记录所有线程
private List<Thread> threads = new List<Thread>();
然后用线程填充列表
public void Run(int strandID)
{
Thread t = new Thread(() => this._run(strandID));
t.Start();
threads.Add(t);
}
最后,您可以为列表中的每个线程调用Join
。通常一个好的做法是有一个超时延迟,所以你的程序不会永远阻塞(如果一个线程中有错误)
public void WaitAll(List<Thread> threads, int maxWaitingTime)
{
foreach (var thread in threads)
{
thread.Join(maxWaitingTime); //throws after timeout expires
}
}
<小时/> 另一种方法是使用
Task
类并致电Task.WaitAll
答案 1 :(得分:1)
让ThreadClass
公开join the thread的方法:
private Thread nativeThread;
public void Run(int strandID)
{
nativeThread = new Thread(() => this._run(strandID));
nativeThread.Start();
}
public void Join()
{
nativeThread.Join();
}
然后在启动它们后在每个线程上使用ThreadClass.Join
:
var threads = new List<ThreadClass>();
for (int i = 0; i <= s.Length; i += lenCutoff)
{
threads.Add(new ThreadClass(s.Substring(i, lenCutoff), i));
threads[threads.Count - 1].Run(strandID);
}
// Waits for each thread to finish in succession
threads.ForEach(t => t.Join());
或者,扔掉ThreadClass
并享受System.Threading.Tasks
:
// e.g. class Models { Complete; Partial; }
// private Models Search(string source, int offset, int length, int ID)
var tasks = new List<Task<Models>>(
from x in Enumerable.Range(0, s.Length / lenCutoff)
select Task.Factory.StartNew<Models>(
() => Search(s, x, lenCutoff, strandID));
);
// private Models CombineResults(IEnumerable<Models> results)
var combine = Task.Factory.ContinueWhenAll<Models>(
tasks.ToArray(),
ts => CombineResults(ts.Select(t => t.Result)));
combine.Wait();
Models combinedModels = combine.Result;
答案 2 :(得分:1)
我看到答案已经被选中了,但我已经开始使用System.Threading.Tasks
编写一个解决方案,正如其他几个人所提出的那样。我没有使用LINQ,而是尝试尽可能地匹配原始代码的结构:
class SearchClass
{
public String InputString { get; private set; }
public int StartPos { get; private set; }
public List<string> completeModels;
public List<string> partialModels;
public SearchClass(string s, int sPos)
{
InputString = s;
StartPos = sPos;
completeModels = new List<string>();
partialModels = new List<string>();
}
public void Run(int strandID)
{
// SearchAlgorithm.SearchInOneDirection(...);
}
// public static void CombineResult(...){ };
}
class Program
{
static void Main(string s, int strandID)
{
int lenCutoff = 10000;
if (s.Length > lenCutoff)
{
var searches = new List<SearchClass>();
var tasks = new List<System.Threading.Tasks.Task>();
for (int i = 0; i < s.Length; i += lenCutoff)
{
SearchClass newSearch = new SearchClass(s.Substring(i, lenCutoff), i);
searches.Add(newSearch);
tasks.Add(System.Threading.Tasks.Task.Factory.StartNew(()=>newSearch.Run(strandID)));
}
System.Threading.Tasks.Task.WaitAll(tasks.ToArray());
// Combine the result
}
}
}