Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Thursday, October 20, 2016

How can I run both of these methods 'at the same time' in .NET 4.5?

How can I run both of these methods 'at the same time' in .NET 4.5?


I have a method which does 2 independent pieces of logic. I was hoping I can run them both at the same time .. and only continue afterwards when both those child methods have completed.

I was trying to get my head around the async/await syntax but I just don't get it.

Here's the code:

public PewPew SomeMethod(Foo foo)  {      var cats = GetAllTheCats(foo);      var food = GetAllTheFood(foo);        return new PewPew                 {                     Cats = cats,                     Food = food                 };  }    private IList GetAllTheCats(Foo foo)  {      // Do stuff, like hit the Db, spin around, dance, jump, etc...      // It all takes some time.      return cats;  }    private IList GetAllTheFood(Foo foo)  {      // Do more stuff, like hit the Db, nom nom noms...      // It all takes some time.      return food;  }  

So with that code above, I want to say : go and get all the cats and food at the same time. Once we're finished, then return a new PewPew.

I'm confused because I'm not sure which classes above are async or return a Task, etc. All of em? just the two private ones? I'm also guessing I need to leverage the Task.WaitAll(tasks) method, but I'm unsure how to setup the tasks to run at the same time.

Suggestions, kind folks?

Answer by Adam Tal for How can I run both of these methods 'at the same time' in .NET 4.5?


You don't have to use async if you're not in an async method or you're using an older version of the .Net framework.. just use Tasks for simplicity:

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  

Answer by Maarten for How can I run both of these methods 'at the same time' in .NET 4.5?


You can use the TPL to wait for multiple tasks while they are running. See here.

Like this:

public PewPew SomeMethod(Foo foo) {      IList cats = null;      IList 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                 };  }  

Answer by Dimitar Dimitrov for How can I run both of these methods 'at the same time' in .NET 4.5?


Adding to the other answers, you could do something like:

public PewPew SomeMethod(Foo foo)  {      Task> catsTask = GetAllTheCatsAsync(foo);      Task> 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> GetAllTheCatsAsync(Foo foo) { await Task.Delay(7000); // wait for a while return new List(); } public async Task> GetAllTheFoodAsync(Foo foo) { await Task.Delay(5000); // wait for a while return new List(); }

Answer by YK1 for How can I run both of these methods 'at the same time' in .NET 4.5?


Here is what you may want to do:

public async Task 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 GetAllTheCats(Foo foo)  {      // Do stuff, like hit the Db, spin around, dance, jump, etc...      // It all takes some time.      return cats;  }    public IList GetAllTheFood(Foo foo)  {      // Do more stuff, like hit the Db, nom nom noms...      // It all takes some time.      return food;  }  

There are two things you need to understand here:

1) What is diff between this:

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

And this:

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

Both will give you similar result in the sense let the 2 async tasks finish and then return new PewPew - however, difference is that Task.WaitAll() will block the current thread (if that is UI thread, then UI will freeze). instead, await will break down the SomeMethod say in a state machine, and return from the SomeMethod to its caller as it encounters await keyword. It will not block the thread. The Code below await will be scheduled to run when async task is over.

2) You could also do this:

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

However, this will not start the async tasks simultaneously. Second task will start after the first is over. This is because how the await keyword works, hope that helps...

EDIT: How to use SomeMethod - somewhere at the start of the call tree, you have to use Wait() or Result property - OR - you have to await from async void. Generally, async void would be an event handler:

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

If not then use Result property.

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

Answer by Matthew Watson for How can I run both of these methods 'at the same time' in .NET 4.5?


By far the easiest way to do this is to use Parallel.Invoke()

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

Parallel.Invoke() will wait for all the methods to return before it itself returns.

More information here: http://msdn.microsoft.com/en-us/library/dd460705.aspx

Note that Parallel.Invoke() handles scaling to the number of processors in your system, but that only really matters if you're starting more than just a couple of tasks.


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

Related Posts:

0 comments:

Post a Comment

Popular Posts

Fun Page

Powered by Blogger.