不带框架函数的C#异步
我有一个使用不同参数运行n次的方法,简化了:不带框架函数的C#异步,c#,asynchronous,C#,Asynchronous,我有一个使用不同参数运行n次的方法,简化了: foreach(var param in params) ValueList.Add(SomeMethod(param)); 我想这样做: foreach(var param in params) TaskList.Add(SomeMethodAsync(param)); foreach(var task in TaskList) ValueList.Add(await task); async Task<Some
foreach(var param in params)
ValueList.Add(SomeMethod(param));
我想这样做:
foreach(var param in params)
TaskList.Add(SomeMethodAsync(param));
foreach(var task in TaskList)
ValueList.Add(await task);
async Task<SomeValue> SomeMethodAsync(SomeParam p)
{
//What to do here
//To make this call async
return SomeMethod(p);
}
foreach(参数中的变量参数)
添加(SomeMethodAsync(param));
foreach(任务列表中的var任务)
添加(等待任务);
异步任务SomeMethodAsync(SomeParam p)
{
//在这里做什么
//使此调用异步
回归分析法(p);
}
如何修改当前方法以应用异步功能?SomeMethod
不使用任何提供异步的框架函数;它是完全同步的
用不同的词来描述它:我希望这个方法的n个任务使用新的async/await关键字异步/同时运行。如果你的方法不返回异步结果,那么使用async/await就没有意义了 如果您只想并行运行方法,请使用
parallel.ForEach
Parallel.ForEach(params, param => ValueList.Add(SomeMethod(param)));
如果SomeMethod不使用任务,或者等待任何框架异步调用,那么它将在单个线程上运行,而不管您是否将异步添加到方法定义中
在这种情况下,最好的选择是在任务中运行SomeMethod
async Task<SomeValue> SomeMethodAsync(SomeParam p)
{
return await Task.Run<SomeValue>(() => SomeMethod(p));
}
async任务SomeMethodAsync(SomeParam p)
{
返回等待任务。运行(()=>SomeMethod(p));
}
我个人认为Parallel.ForEach更清晰。只需将其作为函数返回任务即可
Task<SomeValue> SomeMethodAsync(SomePAram p)
{
return Task<SomeValue>.Run(()=> SomeMethod());
}
Task SomeMethodAsync(SomePAram p)
{
返回Task.Run(()=>SomeMethod());
}
SomeMethodAsync
现在是可等待的。正确,但您应该知道这引入了一个新线程。异步不一定要引入新线程。您可以使用任何类型的任务来等待。@BoasEnkler True,尽管默认的任务调度程序使用线程池,而不是总是旋转新任务。但是,如果问题是要串联运行它们,它们会阻塞,那么异步是没有帮助的。是的,也是正确的:-)但是我考虑了更多关于并发性和数据竞争的问题。所以代码应该是线程安全的。有些行为可能会改变。取决于场景是的,我有点担心ValueList是什么类型,如果它不是线程安全列表,可能会有问题;我想知道我必须对所述方法进行哪些更改才能使其与async/await一起工作。澄清了问题。您需要在返回后添加wait关键字,否则编译器会抱怨返回值必须是SomeValue类型而不是Task。@CameronMacFarland否,请参阅方法声明没有async
,您可能需要读取。另外,您的第二个foreach
循环可以替换为var valueList=wait Task.WhenAll(taskList)代码>。正如我在下面的评论中所写;在我的例子中,我一次与14个不同的服务器通信(不是webrequest或其他异步操作),客户端没有使用任何资源;我只需要等待所有操作完成。但是,无论我是执行parralle.ForEach
,Jobs.aspallel.Select(x=>SomeMethod(x))
还是在使用任务时,操作总和似乎都要花费同样长的时间。(实际上,任务比其他任务花费的时间稍长)时间之和远高于单个操作超时时间。似乎底层框架在内部阻止了查询,对此行为我没有其他解释。