我试过这个......
public ArrayList GetAllObjectAttributes()
{
List<Task> taskList = new List<Task>();
ArrayList allObjectAttributes = new ArrayList();
taskList.Add(Task.Factory.StartNew(() => { allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Folder));}));
taskList.Add(Task.Factory.StartNew(() => { allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.XMLFile)); }));
taskList.Add(Task.Factory.StartNew(() => { allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.TextFile)); }));
taskList.Add(Task.Factory.StartNew(() => { allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Parent)); }));
Task.WaitAll(taskList.ToArray());
return allObjectAttributes;
}
这......
public ArrayList GetAllObjectAttributes()
{
Thread[] threads = new Thread[4];
ArrayList allObjectAttributes = new ArrayList();
threads[0] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Folder)));
threads[1] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.XMLFile)));
threads[2] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.TextFile)));
threads[3] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Parent)));
foreach(Thread thread in threads)
{
thread.Start();
thread.Join();
}
return allObjectAttributes;
}
这也是......
public ArrayList GetAllObjectAttributes()
{
Thread[] threads = new Thread[4];
ArrayList allObjectAttributes = new ArrayList();
threads[0] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Folder)));
threads[1] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.XMLFile)));
threads[2] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.TextFile)));
threads[3] = new Thread(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Parent)));
foreach(Thread thread in threads)
{
thread.Start();
}
while(threads[0].IsAlive || threads[1].IsAlive || threads[2].IsAlive || threads[3].IsAlive)
{
Thread.Sleep(500);
}
return allObjectAttributes;
}
我也试过了 Spawn Multiple Threads for work then wait until all finished
我仍然在allObjectAttributes中的一个arraylist项中得到一个null。
但是,当我这样做时
public ArrayList GetAllObjectAttributes()
{
ArrayList allObjectAttributes = new ArrayList();
allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Folder)));
allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.XMLFile)));
allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.TextFile)));
allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Parent)));
return allObjectAttributes;
}
我从未在arraylist项目中获得null项。
private List GetObjectAttributes(TreeViewAttrs tv) { List objectAttributes = new List(); string command = "COMMAND_TO_EXECUTE"; if (command != "") { List results = RunCommand(command); if (results == null) { return null; } if (results.Count > 0) { foreach (string result in results) { if (!result.Contains("" + tv + "")) { string[] res = reformatResponseString(result); //reformat the strings as per custom structure if (res != null) { objectAttributes.Add(res); } } } return objectAttributes; } } return null; }
答案 0 :(得分:8)
使用线程安全集合(.NET 4.0兼容)略微改进:
List<Task> taskList = new List<Task>();
ConcurrentBag<object> allObjectAttributes = new ConcurrentBag<object>();
taskList.Add(Task.Factory.StartNew(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Folder))));
taskList.Add(Task.Factory.StartNew(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.XMLFile))));
taskList.Add(Task.Factory.StartNew(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.TextFile))));
taskList.Add(Task.Factory.StartNew(() => allObjectAttributes.Add(GetObjectAttributes(TreeViewAttrs.Parent))));
Task.WaitAll(taskList.ToArray());
return allObjectAttributes;
替代方法:完成所有任务后使用Task.Result
(不再需要线程安全集合,因为只有一个线程修改ArrayList
):
Task<object>[] taskList = {
Task.Factory.StartNew(() => (object)GetObjectAttributes(TreeViewAttrs.Folder)),
Task.Factory.StartNew(() => (object)GetObjectAttributes(TreeViewAttrs.XMLFile)),
Task.Factory.StartNew(() => (object)GetObjectAttributes(TreeViewAttrs.TextFile)),
Task.Factory.StartNew(() => (object)GetObjectAttributes(TreeViewAttrs.Parent))
};
Task.WaitAll(taskList);
ArrayList allObjectAttributes = new ArrayList();
foreach (Task<object> task in taskList) {
allObjectAttributes.Add(task.Result);
}
return allObjectAttributes;
使用Task.WhenAll
(仅限.NET 4.5)显着改进:
object[] allObjectAttributes = await Task.WhenAll(
Task.Run(() => GetObjectAttributes(TreeViewAttrs.Folder)),
Task.Run(() => GetObjectAttributes(TreeViewAttrs.XMLFile)),
Task.Run(() => GetObjectAttributes(TreeViewAttrs.TextFile)),
Task.Run(() => GetObjectAttributes(TreeViewAttrs.Parent))
);
return allObjectAttributes;
*注意:我使用object
作为通用参数,因为您保留了GetObjectAttributes
未指定的返回类型。
答案 1 :(得分:0)
您在第一个示例中使用的Task.WaitAll()应该按预期工作。但是,我怀疑你所拥有的问题必须使用你使用的集合的线程安全性,ArrayList,而不是等待所有任务的完成这一事实。 ArrayList不提供线程安全性,因此您应该通过使用锁定机制或通过使用线程安全集合(例如ConcurrentBag(https://msdn.microsoft.com/en-us/library/dd381779(v=vs.110).aspx))来查看其他方法。