0

Whenever I have to start a parallel task I usually do this:

public async Task FindPerson(string personId)
{
    await Task.Run(() =>
    {
        //Search the person and write to screen 
    });
} 

However usually I see other coders using AsAsyncOperation:

public IAsyncAction FindPerson(string personId)
{
    Task t = new Task(() =>
    {
        //Search the person and write to screen 
    });
    t.Start();
    return t.AsAsyncAction();
}

Does anyone have a clue on what benefits AsAsyncAction brings compared to using the brand new async/await?

Fritjof Berggren
  • 3,178
  • 5
  • 35
  • 57

2 Answers2

3

AsAsyncAction is for turning tasks into IAsyncAction to be passed to WinRT. If you don't use WinRT there's no reason to use this extension.

You also shouldn't create a task and then start it. Task.Run is preferred in almost all cases.

You also shouldn't create an async method to just use Task.Run inside it. The caller expects this method to be asynchronous but all it does is offload synchronous work to the ThreadPool. If the caller needs that work on the ThreadPool it's better to let them use Task.Run in their code.

So basically just do this:

public void FindPerson(string personId)
{
    // Search the person and write to screen 
}

And let the caller call this method synchronously, or on a ThreadPool thread:

Task.Run(() => FindPerson(personId));
i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • i'm not very keen on the entire concept of the await keyword as it just encourages people to write synchronous code under the mistaken impression that its Asynchronous – MikeT May 19 '16 at 10:44
  • Hi i3arnon, thanks for the answer, but what do you mean when you speak about WinRT? I'm building a x86 Universal App for Win10. – Fritjof Berggren Jun 06 '16 at 07:19
  • @FernandoUrkijoCereceda WinRT is the windows runtime. It's what you use when you make a windows "modern" app or, I assume, a universal windows app. – i3arnon Jun 06 '16 at 08:06
  • Yes, so as I'm building an universal win 10 app in C#, I assume I'm in top of WinRT. So are the Tasks using AsAsyncAction internally and I don't have to care or just keep using async + await + Task? – Fritjof Berggren Jun 06 '16 at 09:25
  • 1
    @FernandoUrkijoCereceda as far as I know you can use async await normally. If you need to pass IAsyncAction to a WinRT API though you may need to use AsAsyncAction, but only if there's a reason to. – i3arnon Jun 06 '16 at 12:29
  • I disagree with the notion that Task.Run is somehow better in most cases. In many cases you want to handle things after the tasks complete with ContinueWith etc. You may have additional things to setup as well – visc Feb 13 '18 at 06:09
  • 1
    @visc you can use `ContinueWith` after `Task.Run`. – i3arnon Feb 13 '18 at 10:02
  • @i3arnon true, I guess I was more pointing to the fact that you might have additional setup to do. Like multiple tasks and wait all etc or something – visc Feb 13 '18 at 14:45
  • @visc this too can be done with `Task.Run`. Creating a task directly is useful when you want to separate the parts that create the tasks from the parts that execute them, and that's very rare. – i3arnon Feb 13 '18 at 15:53
  • @i3arnon look at the remarks though https://msdn.microsoft.com/en-us/library/hh195051(v=vs.110).aspx I mean if you want to start the task right away then it's good – visc Feb 13 '18 at 16:13
  • @visc and as I said, you **almost never** want the task to not start right away. – i3arnon Feb 13 '18 at 17:45
  • @i3arnon I think you said, "is preferred in almost all cases". Task.Run is pretty limited and just fires and runs. Sure you get handle to it. But god forbid you need to kill the app and keep things hunky dory. How do you cancel it gracefully? I guess I learn more into getting things in full control then firing a task instead of just go for it. – visc Feb 13 '18 at 18:00
  • @visc you cancel it with a cancellation token, exactly the same way you would cancel any other task. `Task.Run` is **indeed** preferred is almost all cases, which is why you've yet to find a single case where it isn't. – i3arnon Feb 13 '18 at 20:56
0

if you look at the MSDN page you will see that for IAsyncAction

  • .NET Framework Supported in: 4.6, 4.5
  • .NET for Windows Phone apps: Supported in: Windows Phone Silverlight 8

if you compare this to Task you will see

  • Universal Windows Platform: Available since 4.5
  • .NET Framework: Available since 4.0
  • Portable Class Library Supported in: portable .NET platforms
  • Silverlight: Available since 5.0
  • Windows Phone Silverlight Available since 8.0
  • Windows Phone Available since 8.1

this instantly tells you that IAsyncAction was created specifically for WinRT, which was MS's first real attempt at an Mobile App framework, because the full .net framework was too powerful to be safe on mobile devices they created a parallel cut down framework that would make it much harder to write malicious software that could damage a device

so if you are using WinRT then returning an IAsyncAction would be preferred anywhere else task

MikeT
  • 5,398
  • 3
  • 27
  • 43
  • I voted down this answer. IAsyncAction is more heavy-weight than Task (since it involves interop with WinRT). You should ONLY turn a Task into an IAsyncAction if you're passing it to a WinRT API which requires an IAsyncAction. This is a very rare scenario. In all other cases, you should stick just with Task. – Lucian Wischik Jun 04 '16 at 04:52
  • So you voted it down because the answer says exactly what you said bar not stating IAsyncAction is heavier? I thought the idea of down voting was to indicate that an answer was incorrect misleading or plain off topic not as a means picking fault with the wording, which is what i thought the edit button was for – MikeT Jun 06 '16 at 13:16