创建返回任务的方法<list <mydataobject>&gt; FOO()</列表<mydataobject>

时间:2014-08-04 17:43:43

标签: c# task-parallel-library

我可以在.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的第二个选项。

2 个答案:

答案 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);
}