Pur*_*ome 39 .net c# task multitasking async-await
我有一个方法,它可以完成两个独立的逻辑.我希望我可以运行他们都在同一时间 ..当这两个孩子的方法完成事后才继续.
我试图弄清楚async/await
语法,但我只是不明白.
这是代码:
public PewPew SomeMethod(Foo foo)
{
var cats = GetAllTheCats(foo);
var food = GetAllTheFood(foo);
return new PewPew
{
Cats = cats,
Food = food
};
}
private IList<Cat> GetAllTheCats(Foo foo)
{
// Do stuff, like hit the Db, spin around, dance, jump, etc...
// It all takes some time.
return cats;
}
private IList<Food> GetAllTheFood(Foo foo)
{
// Do more stuff, like hit the Db, nom nom noms...
// It all takes some time.
return food;
}
Run Code Online (Sandbox Code Playgroud)
因此,根据上面的代码,我想说:去同时获取所有的猫和食物.一旦我们完成,然后返回一个新的PewPew
.
我很困惑,因为我不确定上面哪些课程async
或者返回Task
等等.所有的em?只是两个私人的?我也猜测我需要利用这个Task.WaitAll(tasks)
方法,但我不确定如何设置任务同时运行.
建议,善良的人?
YK1*_*YK1 51
以下是您可能想要做的事情:
public async Task<PewPew> SomeMethod(Foo foo)
{
// get the stuff on another thread
var cTask = Task.Run(() => GetAllTheCats(foo));
var fTask = Task.Run(() => GetAllTheFood(foo));
var cats = await cTask;
var food = await fTask;
return new PewPew
{
Cats = cats,
Food = food
};
}
public IList<Cat> GetAllTheCats(Foo foo)
{
// Do stuff, like hit the Db, spin around, dance, jump, etc...
// It all takes some time.
return cats;
}
public IList<Food> GetAllTheFood(Foo foo)
{
// Do more stuff, like hit the Db, nom nom noms...
// It all takes some time.
return food;
}
Run Code Online (Sandbox Code Playgroud)
这里有两件事你需要理解:
1)这之间有什么区别:
var cats = await cTask;
var food = await fTask;
Run Code Online (Sandbox Code Playgroud)
还有这个:
Task.WaitAll(new [] {cTask, fTask});
Run Code Online (Sandbox Code Playgroud)
两者都会给你类似的结果,让2个async
任务完成然后return new PewPew
- 然而,区别是Task.WaitAll()
会阻塞当前线程(如果是UI线程,那么UI将冻结).相反,await
它将SomeMethod
在状态机中分解,并在SomeMethod
遇到await
关键字时从其返回到其调用者.它不会阻止线程.下面的代码await
将安排在async
任务结束时运行.
2)你也可以这样做:
var cats = await Task.Run(() => GetAllTheCats(foo));
var food = await Task.Run(() => GetAllTheFood(foo));
Run Code Online (Sandbox Code Playgroud)
但是,这不会async
同时启动任务.第二项任务将在第一项任务结束后开始.这是因为await
关键字如何工作,希望有帮助......
编辑:如何使用SomeMethod
- 在调用树的开头某处,你必须使用Wait()
或Result
属性 - 或 - 你必须await
从async void
.通常,async void
将是一个事件处理程序:
public async void OnSomeEvent(object sender, EventArgs ez)
{
Foo f = GetFoo();
PewPew p = await SomeMethod(f);
}
Run Code Online (Sandbox Code Playgroud)
如果没有,那么使用Result
财产.
public Foo2 NonAsyncNonVoidMethod()
{
Foo f = GetFoo();
PewPew p = SomeMethod(f).Result; //But be aware that Result will block thread
return GetFoo2(p);
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*son 20
到目前为止,最简单的方法是使用 Parallel.Invoke()
IList<Cat> cats;
IList<Food> food;
Parallel.Invoke
(
() => cats = GetAllTheCats(foo),
() => food = GetAllTheFood(foo)
);
Run Code Online (Sandbox Code Playgroud)
Parallel.Invoke()
将等待所有方法返回之前返回.
更多信息:http://msdn.microsoft.com/en-us/library/dd460705.aspx
请注意,Parallel.Invoke()
处理扩展到系统中处理器的数量,但这只是在您开始的不仅仅是几项任务时才真正重要.
Ada*_*Tal 10
如果您不使用异步方法或者使用旧版本的.Net框架,则不必使用async.只需使用Tasks来简化:
Task taskA = Task.Factory.StartNew(() => GetAllTheCats(foo));
Task taskB = Task.Factory.StartNew(() => GetAllTheFood(foo));
Task.WaitAll(new [] { taskA, taskB });
// Will continue after both tasks completed
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
39628 次 |
最近记录: |