当TResult是Task <object>时,如何使用Task.Factory.StartNew <tresult>

时间:2015-07-16 19:50:04

标签: c# asynchronous async-await task-parallel-library

使用任务并行库遇到一些障碍,调用返回任务的方法。

我有一个名为MspClient的类,它包含一个名为MakeMspCallAsync的异步方法

public class MspClient
{        
    public async Task<IMspCallResponse> MakeMspCallAsync(IMspCallRequest request)
    {
        var response = new MspCallResponse();
        ... 
        await ...
        ...
        return response;
    }
}  

在我使用MspClient类的程序中,我想写下这些内容:

using (var mspClient = new MspClient())
{
    Task<IMspCallResponse>[] tasks = new Task<IMspCallResponse>[ctx.Message.MspCallRequests.Count];

    for(int i = 0; i < ctx.Message.MspCallRequests.Count; i++)
    {
        var mspCallRequest = ctx.Message.MspCallRequests[i];        
        tasks[i] = Task.Factory.StartNew<IMspCallResponse>(mspClient.MakeMspCallAsync(mspCallRequest));
    }

    Task.WaitAll(tasks);
}

此行发生编译时异常:

tasks[i] = Task.Factory.StartNew<IMspCallResponse>(mspClient.MakeMspCallAsync(mspCallRequest));

Error   1   The best overloaded method match for 'System.Threading.Tasks.TaskFactory.StartNew<IMspCallResponse>(System.Func<IMspCallResponse>)' has some invalid arguments  

Error   2   Argument 1: cannot convert from 'System.Threading.Tasks.Task<IMspCallResponse>' to 'System.Func<IMspCallResponse>'

非常确定我忽略了一些非常简单的事情,但无法绕过它,有人可以帮助我吗?感谢。

1 个答案:

答案 0 :(得分:2)

你至少需要一个代表:

Task.Factory.StartNew<IMspCallResponse>(() => mspClient.MakeMspCallAsync(mspCallRequest));

然而,这将返回Task<Task<IMspCallResponse>>,这有点不合适。您需要打开它(请参阅TaskExtensions.Unwrap)。 Task.Run更好,因为它会为你做到这一点:

tasks[i] = Task.Run(() => mspClient.MakeMspCallAsync(mspCallRequest));