tasks run parallel multiple method ejemplo create await async c# .net task async-await multitasking

parallel - task run async c#



¿Cómo puedo ejecutar estos dos métodos ''al mismo tiempo'' en.NET 4.5? (5)

Agregando a las otras respuestas, podrías hacer algo como:

public PewPew SomeMethod(Foo foo) { Task<IList<Cat>> catsTask = GetAllTheCatsAsync(foo); Task<IList<Food>> foodTask = GetAllTheFoodAsync(foo); // wait for both tasks to complete Task.WaitAll(catsTask, foodTask); return new PewPew { Cats = catsTask.Result, Food = foodTask.Result }; } public async Task<IList<Cat>> GetAllTheCatsAsync(Foo foo) { await Task.Delay(7000); // wait for a while return new List<Cat>(); } public async Task<IList<Food>> GetAllTheFoodAsync(Foo foo) { await Task.Delay(5000); // wait for a while return new List<Food>(); }

Tengo un método que hace 2 piezas independientes de lógica. Esperaba poder ejecutar ambos al mismo tiempo ... y continuar luego cuando ambos métodos secundarios se hayan completado.

Estaba tratando de entender mi sintaxis async/await pero simplemente no lo entiendo.

Aquí está el código:

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; }

Entonces, con ese código anterior, quiero decir: ve y consigue todos los gatos y la comida al mismo tiempo. Una vez que hayamos terminado, devuelve un nuevo PewPew .

Estoy confundido porque no estoy seguro de qué clases de arriba son async o devuelven una Task , etc. ¿Todas ellas? solo los dos privados? También estoy adivinando que necesito aprovechar el Task.WaitAll(tasks) , pero no estoy seguro de cómo configurar las tareas para que se ejecuten al mismo tiempo.

Sugerencias, amable gente?


Esto es lo que puede querer hacer:

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; }

Hay dos cosas que debes entender aquí:

1) ¿Cuál es la diferencia entre esto?

var cats = await cTask; var food = await fTask;

Y esto:

Task.WaitAll(new [] {cTask, fTask});

Ambos le darán resultados similares en el sentido de dejar que las 2 tareas async finalicen y luego return new PewPew ; sin embargo, la diferencia es que Task.WaitAll() bloqueará el hilo actual (si ese es el hilo de UI, la IU se congelará). en su lugar, await descompondrá el SomeMethod decir en una máquina de estado, y regresará desde SomeMethod a su interlocutor cuando encuentre la palabra clave SomeMethod . No bloqueará el hilo. El código debajo de await se programará para ejecutarse cuando async tarea async .

2) También puedes hacer esto:

var cats = await Task.Run(() => GetAllTheCats(foo)); var food = await Task.Run(() => GetAllTheFood(foo));

Sin embargo, esto no iniciará las tareas async simultáneamente. La segunda tarea comenzará una vez que termine la primera. Esto se debe a cómo funciona la palabra clave await, espero que ayude ...

EDITAR: Cómo usar SomeMethod : en algún lugar al comienzo del árbol de llamadas, debe usar Wait() o Result property - O - debe await de async void . En general, async void sería un controlador de eventos:

public async void OnSomeEvent(object sender, EventArgs ez) { Foo f = GetFoo(); PewPew p = await SomeMethod(f); }

Si no, use la propiedad Result .

public Foo2 NonAsyncNonVoidMethod() { Foo f = GetFoo(); PewPew p = SomeMethod(f).Result; //But be aware that Result will block thread return GetFoo2(p); }


La forma más fácil de hacer esto es usar Parallel.Invoke()

IList<Cat> cats; IList<Food> food; Parallel.Invoke ( () => cats = GetAllTheCats(foo), () => food = GetAllTheFood(foo) );

Parallel.Invoke() esperará a que todos los métodos vuelvan antes de que regrese.

Más información aquí: http://msdn.microsoft.com/en-us/library/dd460705.aspx

Tenga en cuenta que Parallel.Invoke() maneja la escala de la cantidad de procesadores en su sistema, pero eso solo importa si está comenzando más que solo un par de tareas.


No tiene que usar la función asincrónica si no utiliza un método asíncrono o está usando una versión anterior de .Net framework. Solo use Tareas para simplificar:

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


Puede usar el TPL para esperar múltiples tareas mientras se están ejecutando. Mira here .

Me gusta esto:

public PewPew SomeMethod(Foo foo) { IList<Cat> cats = null; IList<Food> foods = null; Task[] tasks = new tasks[2] { Task.Factory.StartNew(() => { cats = GetAllTheCats(foo); }), Task.Factory.StartNew(() => { food = GetAllTheFood(foo); }) }; Task.WaitAll(tasks); return new PewPew { Cats = cats, Food = food }; }