我可以在.Net 4.5中解决这个问题,但我必须在.Net 4.0中解决它,到目前为止我还没有成功。
我无法将回复转换为Task<List<MyDataObject>>
。以下代码可以创建List<MyDataObject>
。
public Task<List<MyDataObject>> Foo()
{
IEnumerable<string> names = GetList();
var tasks = new List<Task>();
foreach (var name in names)
{ tasks.Add(Task<MyDataObject>.Factory.StartNew(
() =>
{
var reply = new MyDataObject();
var workerObject = new WorkerObject();
workerObject.Foo2();
reply.Success = true;
return reply;
}));
}
Task.WaitAll(tasks.ToArray());
var replyList = new List<MyDataObject>();
for (int i = 0; i < tasks.Count(); i++)
{ replyList.Add(((Task<MyDataObject>)tasks[i]).Result);
}
return replyList;
}
WhenAll()
仅为4.5
await
仅为4.5
所以我不能接受那些
我同意这不会编译。我展示的是我可以遍历结果。但是我不知道怎么去
List<MyDataObject>()
到
Task<List<MyDataObject>>
感谢您的回复。我将接受Yuval Itzchakov的回答,因为它以简单的方式解决了我的问题。我仅限于此用例没有新的程序集。如果我有另一种需要此功能的方法,我会选择280Z28的第二个选项。
答案 0 :(得分:2)
使用TaskCompletionSource<List<MyDataObject>>
Task.WaitAll(tasks.ToArray());
var replyList = new List<MyDataObject>();
for (int i = 0; i < tasks.Count(); i++)
{
replyList.Add(((Task<MyDataObject>)tasks[i]).Result);
}
var tcs = new TaskCompletionSource<List<MyDataObject>>();
tcs.SetResult(replyList);
return tcs.Task;
您也可以下载Microsoft.Bcl.Async
来获取
NET 4.5中的.NET 4.5效果
答案 1 :(得分:1)
如果您按照以下步骤操作,您将在.NET 4.0中获得完全相同的行为:
WhenAll
方法public static Task<TResult[]> WhenAll<TResult>(IEnumerable<Task<TResult>> tasks)
{
TaskCompletionSource<TResult[]> taskCompletionSource = new TaskCompletionSource<TResult[]>();
Action<Task<TResult>[]> continuationAction =
completedTasks =>
{
List<TResult> results = new List<TResult>();
List<Exception> exceptions = new List<Exception>();
bool canceled = false;
foreach (var completedTask in completedTasks)
{
switch (completedTask.Status)
{
case TaskStatus.RanToCompletion:
results.Add(completedTask.Result);
break;
case TaskStatus.Canceled:
canceled = true;
break;
case TaskStatus.Faulted:
exceptions.AddRange(completedTask.Exception.InnerExceptions);
break;
default:
throw new InvalidOperationException("Unreachable");
}
}
if (exceptions.Count > 0)
taskCompletionSource.SetException(exceptions);
else if (canceled)
taskCompletionSource.SetCanceled();
else
taskCompletionSource.SetResult(results.ToArray());
};
Task.Factory.ContinueWhenAll(tasks.ToArray(), continuationAction);
return taskCompletionSource.Task;
}
Select
中的Rackspace Threading Library方法返回预期结果public Task<List<MyDataObject>> Foo()
{
IEnumerable<string> names = GetList();
var tasks = new List<Task<MyDataObject>>();
foreach (var name in names)
{
tasks.Add(Task<MyDataObject>.Factory.StartNew(
() =>
{
var reply = new MyDataObject();
var workerObject = new WorkerObject();
workerObject.Foo2();
reply.Success = true;
return reply;
}));
}
return WhenAll(tasks).Select(result => new List<MyDataObject>(result.Result));
}
作为替代方案,您可以修改上面的WhenAll
方法以返回Task<List<TResult>>
而不是Task<TResult[]>
。这将允许您简单地使用以下方法。
public Task<List<MyDataObject>> Foo()
{
IEnumerable<string> names = GetList();
var tasks = new List<Task<MyDataObject>>();
foreach (var name in names)
{
tasks.Add(Task<MyDataObject>.Factory.StartNew(
() =>
{
var reply = new MyDataObject();
var workerObject = new WorkerObject();
workerObject.Foo2();
reply.Success = true;
return reply;
}));
}
return WhenAll(tasks);
}