Fire-and-forget with async vs “old async delegate”












52















I am trying to replace my old fire-and-forget calls with a new syntax, hoping for more simplicity and it seems to be eluding me. Here's an example



class Program
{
static void DoIt(string entry)
{
Console.WriteLine("Message: " + entry);
}

static async void DoIt2(string entry)
{
await Task.Yield();
Console.WriteLine("Message2: " + entry);
}

static void Main(string args)
{
// old way
Action<string> async = DoIt;
async.BeginInvoke("Test", ar => { async.EndInvoke(ar); ar.AsyncWaitHandle.Close(); }, null);
Console.WriteLine("old-way main thread invoker finished");
// new way
DoIt2("Test2");
Console.WriteLine("new-way main thread invoker finished");
Console.ReadLine();
}
}


Both approaches do the same thing, however what I seem to have gained (no need to EndInvoke and close handle, which is imho still a bit debatable) I am losing in the new way by having to await a Task.Yield(), which actually poses a new problem of having to rewrite all existing async F&F methods just to add that one-liner. Are there some invisible gains in terms of performance/cleanup?



How would I go about applying async if I can't modify the background method? Seems to me that there is no direct way, I would have to create a wrapper async method that would await Task.Run()?



Edit: I now see I might be missing a real questions. The question is: Given a synchronous method A(), how can I call it asynchronously using async/await in a fire-and-forget manner without getting a solution that is more complicated than the "old way"










share|improve this question




















  • 1





    async/await is not really designed for offloading synchronous workloads onto another thread. I've used async/await in some pretty huge projects with not a Thread.Yield in sight. I see this code as an abuse of the the async await philosophy. If there's no async IO, async/await is probably the wrong solution.

    – spender
    Oct 9 '12 at 15:23













  • I would disagree, especially in my case; there is no sound reason to force http requestor to wait for a complete process to finish to receive a response available at the very begining. The rest can be safely offloaded. The only question really is can async/await help, make worse or is just unusable in this scenario. I must admit I had different ideas about what it was.

    – mmix
    Oct 9 '12 at 15:41






  • 1





    I don't disagree that the work might need offloading. I'm saying that using async/await combined with Task.Yield has a bad smell. Using ThreadPool.QueueUserWorkItem would be a better fit here. After all, that's really what you're trying to do... send the work to the ThreadPool with a resonably minimal code footprint, right?

    – spender
    Oct 9 '12 at 15:45








  • 1





    oh, ok. fair comment, I misunderstood your claim. I guess I just thought that with async I'll just call a method and it will magically start on another thread :). Speaking of different approaches, does anyone know of a comparison between the three? ThreadPool.QueueUserWorkItem vs Task.Factory.StartNew vs delegate.BeginInvoke? If I am going to make changes, I might as well do it in the best available way.

    – mmix
    Oct 9 '12 at 15:49


















52















I am trying to replace my old fire-and-forget calls with a new syntax, hoping for more simplicity and it seems to be eluding me. Here's an example



class Program
{
static void DoIt(string entry)
{
Console.WriteLine("Message: " + entry);
}

static async void DoIt2(string entry)
{
await Task.Yield();
Console.WriteLine("Message2: " + entry);
}

static void Main(string args)
{
// old way
Action<string> async = DoIt;
async.BeginInvoke("Test", ar => { async.EndInvoke(ar); ar.AsyncWaitHandle.Close(); }, null);
Console.WriteLine("old-way main thread invoker finished");
// new way
DoIt2("Test2");
Console.WriteLine("new-way main thread invoker finished");
Console.ReadLine();
}
}


Both approaches do the same thing, however what I seem to have gained (no need to EndInvoke and close handle, which is imho still a bit debatable) I am losing in the new way by having to await a Task.Yield(), which actually poses a new problem of having to rewrite all existing async F&F methods just to add that one-liner. Are there some invisible gains in terms of performance/cleanup?



How would I go about applying async if I can't modify the background method? Seems to me that there is no direct way, I would have to create a wrapper async method that would await Task.Run()?



Edit: I now see I might be missing a real questions. The question is: Given a synchronous method A(), how can I call it asynchronously using async/await in a fire-and-forget manner without getting a solution that is more complicated than the "old way"










share|improve this question




















  • 1





    async/await is not really designed for offloading synchronous workloads onto another thread. I've used async/await in some pretty huge projects with not a Thread.Yield in sight. I see this code as an abuse of the the async await philosophy. If there's no async IO, async/await is probably the wrong solution.

    – spender
    Oct 9 '12 at 15:23













  • I would disagree, especially in my case; there is no sound reason to force http requestor to wait for a complete process to finish to receive a response available at the very begining. The rest can be safely offloaded. The only question really is can async/await help, make worse or is just unusable in this scenario. I must admit I had different ideas about what it was.

    – mmix
    Oct 9 '12 at 15:41






  • 1





    I don't disagree that the work might need offloading. I'm saying that using async/await combined with Task.Yield has a bad smell. Using ThreadPool.QueueUserWorkItem would be a better fit here. After all, that's really what you're trying to do... send the work to the ThreadPool with a resonably minimal code footprint, right?

    – spender
    Oct 9 '12 at 15:45








  • 1





    oh, ok. fair comment, I misunderstood your claim. I guess I just thought that with async I'll just call a method and it will magically start on another thread :). Speaking of different approaches, does anyone know of a comparison between the three? ThreadPool.QueueUserWorkItem vs Task.Factory.StartNew vs delegate.BeginInvoke? If I am going to make changes, I might as well do it in the best available way.

    – mmix
    Oct 9 '12 at 15:49
















52












52








52


20






I am trying to replace my old fire-and-forget calls with a new syntax, hoping for more simplicity and it seems to be eluding me. Here's an example



class Program
{
static void DoIt(string entry)
{
Console.WriteLine("Message: " + entry);
}

static async void DoIt2(string entry)
{
await Task.Yield();
Console.WriteLine("Message2: " + entry);
}

static void Main(string args)
{
// old way
Action<string> async = DoIt;
async.BeginInvoke("Test", ar => { async.EndInvoke(ar); ar.AsyncWaitHandle.Close(); }, null);
Console.WriteLine("old-way main thread invoker finished");
// new way
DoIt2("Test2");
Console.WriteLine("new-way main thread invoker finished");
Console.ReadLine();
}
}


Both approaches do the same thing, however what I seem to have gained (no need to EndInvoke and close handle, which is imho still a bit debatable) I am losing in the new way by having to await a Task.Yield(), which actually poses a new problem of having to rewrite all existing async F&F methods just to add that one-liner. Are there some invisible gains in terms of performance/cleanup?



How would I go about applying async if I can't modify the background method? Seems to me that there is no direct way, I would have to create a wrapper async method that would await Task.Run()?



Edit: I now see I might be missing a real questions. The question is: Given a synchronous method A(), how can I call it asynchronously using async/await in a fire-and-forget manner without getting a solution that is more complicated than the "old way"










share|improve this question
















I am trying to replace my old fire-and-forget calls with a new syntax, hoping for more simplicity and it seems to be eluding me. Here's an example



class Program
{
static void DoIt(string entry)
{
Console.WriteLine("Message: " + entry);
}

static async void DoIt2(string entry)
{
await Task.Yield();
Console.WriteLine("Message2: " + entry);
}

static void Main(string args)
{
// old way
Action<string> async = DoIt;
async.BeginInvoke("Test", ar => { async.EndInvoke(ar); ar.AsyncWaitHandle.Close(); }, null);
Console.WriteLine("old-way main thread invoker finished");
// new way
DoIt2("Test2");
Console.WriteLine("new-way main thread invoker finished");
Console.ReadLine();
}
}


Both approaches do the same thing, however what I seem to have gained (no need to EndInvoke and close handle, which is imho still a bit debatable) I am losing in the new way by having to await a Task.Yield(), which actually poses a new problem of having to rewrite all existing async F&F methods just to add that one-liner. Are there some invisible gains in terms of performance/cleanup?



How would I go about applying async if I can't modify the background method? Seems to me that there is no direct way, I would have to create a wrapper async method that would await Task.Run()?



Edit: I now see I might be missing a real questions. The question is: Given a synchronous method A(), how can I call it asynchronously using async/await in a fire-and-forget manner without getting a solution that is more complicated than the "old way"







c# asynchronous c#-5.0






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Oct 9 '12 at 15:17







mmix

















asked Oct 9 '12 at 15:04









mmixmmix

4,49222555




4,49222555








  • 1





    async/await is not really designed for offloading synchronous workloads onto another thread. I've used async/await in some pretty huge projects with not a Thread.Yield in sight. I see this code as an abuse of the the async await philosophy. If there's no async IO, async/await is probably the wrong solution.

    – spender
    Oct 9 '12 at 15:23













  • I would disagree, especially in my case; there is no sound reason to force http requestor to wait for a complete process to finish to receive a response available at the very begining. The rest can be safely offloaded. The only question really is can async/await help, make worse or is just unusable in this scenario. I must admit I had different ideas about what it was.

    – mmix
    Oct 9 '12 at 15:41






  • 1





    I don't disagree that the work might need offloading. I'm saying that using async/await combined with Task.Yield has a bad smell. Using ThreadPool.QueueUserWorkItem would be a better fit here. After all, that's really what you're trying to do... send the work to the ThreadPool with a resonably minimal code footprint, right?

    – spender
    Oct 9 '12 at 15:45








  • 1





    oh, ok. fair comment, I misunderstood your claim. I guess I just thought that with async I'll just call a method and it will magically start on another thread :). Speaking of different approaches, does anyone know of a comparison between the three? ThreadPool.QueueUserWorkItem vs Task.Factory.StartNew vs delegate.BeginInvoke? If I am going to make changes, I might as well do it in the best available way.

    – mmix
    Oct 9 '12 at 15:49
















  • 1





    async/await is not really designed for offloading synchronous workloads onto another thread. I've used async/await in some pretty huge projects with not a Thread.Yield in sight. I see this code as an abuse of the the async await philosophy. If there's no async IO, async/await is probably the wrong solution.

    – spender
    Oct 9 '12 at 15:23













  • I would disagree, especially in my case; there is no sound reason to force http requestor to wait for a complete process to finish to receive a response available at the very begining. The rest can be safely offloaded. The only question really is can async/await help, make worse or is just unusable in this scenario. I must admit I had different ideas about what it was.

    – mmix
    Oct 9 '12 at 15:41






  • 1





    I don't disagree that the work might need offloading. I'm saying that using async/await combined with Task.Yield has a bad smell. Using ThreadPool.QueueUserWorkItem would be a better fit here. After all, that's really what you're trying to do... send the work to the ThreadPool with a resonably minimal code footprint, right?

    – spender
    Oct 9 '12 at 15:45








  • 1





    oh, ok. fair comment, I misunderstood your claim. I guess I just thought that with async I'll just call a method and it will magically start on another thread :). Speaking of different approaches, does anyone know of a comparison between the three? ThreadPool.QueueUserWorkItem vs Task.Factory.StartNew vs delegate.BeginInvoke? If I am going to make changes, I might as well do it in the best available way.

    – mmix
    Oct 9 '12 at 15:49










1




1





async/await is not really designed for offloading synchronous workloads onto another thread. I've used async/await in some pretty huge projects with not a Thread.Yield in sight. I see this code as an abuse of the the async await philosophy. If there's no async IO, async/await is probably the wrong solution.

– spender
Oct 9 '12 at 15:23







async/await is not really designed for offloading synchronous workloads onto another thread. I've used async/await in some pretty huge projects with not a Thread.Yield in sight. I see this code as an abuse of the the async await philosophy. If there's no async IO, async/await is probably the wrong solution.

– spender
Oct 9 '12 at 15:23















I would disagree, especially in my case; there is no sound reason to force http requestor to wait for a complete process to finish to receive a response available at the very begining. The rest can be safely offloaded. The only question really is can async/await help, make worse or is just unusable in this scenario. I must admit I had different ideas about what it was.

– mmix
Oct 9 '12 at 15:41





I would disagree, especially in my case; there is no sound reason to force http requestor to wait for a complete process to finish to receive a response available at the very begining. The rest can be safely offloaded. The only question really is can async/await help, make worse or is just unusable in this scenario. I must admit I had different ideas about what it was.

– mmix
Oct 9 '12 at 15:41




1




1





I don't disagree that the work might need offloading. I'm saying that using async/await combined with Task.Yield has a bad smell. Using ThreadPool.QueueUserWorkItem would be a better fit here. After all, that's really what you're trying to do... send the work to the ThreadPool with a resonably minimal code footprint, right?

– spender
Oct 9 '12 at 15:45







I don't disagree that the work might need offloading. I'm saying that using async/await combined with Task.Yield has a bad smell. Using ThreadPool.QueueUserWorkItem would be a better fit here. After all, that's really what you're trying to do... send the work to the ThreadPool with a resonably minimal code footprint, right?

– spender
Oct 9 '12 at 15:45






1




1





oh, ok. fair comment, I misunderstood your claim. I guess I just thought that with async I'll just call a method and it will magically start on another thread :). Speaking of different approaches, does anyone know of a comparison between the three? ThreadPool.QueueUserWorkItem vs Task.Factory.StartNew vs delegate.BeginInvoke? If I am going to make changes, I might as well do it in the best available way.

– mmix
Oct 9 '12 at 15:49







oh, ok. fair comment, I misunderstood your claim. I guess I just thought that with async I'll just call a method and it will magically start on another thread :). Speaking of different approaches, does anyone know of a comparison between the three? ThreadPool.QueueUserWorkItem vs Task.Factory.StartNew vs delegate.BeginInvoke? If I am going to make changes, I might as well do it in the best available way.

– mmix
Oct 9 '12 at 15:49














4 Answers
4






active

oldest

votes


















72














Avoid async void. It has tricky semantics around error handling; I know some people call it "fire and forget" but I usually use the phrase "fire and crash".




The question is: Given a synchronous method A(), how can I call it asynchronously using async/await in a fire-and-forget manner without getting a solution that is more complicated than the "old way"




You don't need async / await. Just call it like this:



Task.Run(A);





share|improve this answer



















  • 4





    what if A() has async method calls in it?

    – Anthony Johnston
    Jan 26 '13 at 11:32






  • 2





    I mean, how do you avoid the warnings about not awaiting a task?

    – Anthony Johnston
    Jan 26 '13 at 11:40








  • 13





    That warning is there because fire-and-forget in an async method is almost certainly a mistake. If you're positively sure that's what you want to do, you can assign the result to an unused local variable like this: var _ = Task.Run(A);

    – Stephen Cleary
    Jan 26 '13 at 14:12











  • Thanks Stephen, and, yes, fire and forget is what I want, its a socket accept loop, async void seems perfect. Given that the method always properly handles exceptions (jaylee.org/post/2012/07/08/…) would you agree or am I just going to get in a pickle?

    – Anthony Johnston
    Jan 26 '13 at 15:03






  • 4





    @AnthonyJohnston: I meant calling a fire-and-forget method from an async method is almost certainly a mistake. In your case, since you always handle exceptions within the method, there's little difference between async Task and async void. I would still lean a bit more towards async Task, just because async void to me implies "event handler".

    – Stephen Cleary
    Jan 26 '13 at 15:52



















39














As noted in the other answers, and by this excellent blog post you want to avoid using async void outside of UI event handlers. If you want a safe "fire and forget" async method, consider using this pattern (credit to @ReedCopsey; this method is one he gave to me in a chat conversation):





  1. Create an extension method for Task. It runs the passed Task and catches/logs any exceptions:



    static async void FireAndForget(this Task task)
    {
    try
    {
    await task;
    }
    catch (Exception e)
    {
    // log errors
    }
    }


  2. Always use Task style async methods when creating them, never async void.



  3. Invoke those methods this way:



    MyTaskAsyncMethod().FireAndForget();



You don't need to await it (nor will it generate the await warning). It will also handle any errors correctly, and as this is the only place you ever put async void, you don't have to remember to put try/catch blocks everywhere.



This also gives you the option of not using the async method as a "fire and forget" method if you actually want to await it normally.






share|improve this answer





















  • 2





    Well, if I have a Task, I'll just Run it, no?

    – mmix
    Jan 12 '15 at 16:13






  • 2





    @mmix That depends, you could use a Task object and run it, but thats not using await/async. This is how you do "fire and forget" with await/async. Note that this is much more useful when you are invoking Async framework methods, and you want to use them in a "fire and forget" sort of way.

    – BradleyDotNET
    Jan 12 '15 at 17:07






  • 2





    Hi, its an old post, but generally the idea was to use language "flow" elements to achieve fire and forget, without implicitly using Task object as such. WE came to a conclusion that its not possible since calling async does not raise new thread until it awaits. If I have Task object then I just Run()-it and it will fire and forget.

    – mmix
    Jan 18 '15 at 10:58











  • @mmix No problem, this just came up in a discussion I had with Reed Copsey, and in a separate question we had a discussion about using async void to do fire-and-forget where I was pointed to this question as to why not to do that. I was adding this as the "correct" way to utilize async void to do that.

    – BradleyDotNET
    Jan 18 '15 at 18:33








  • 1





    @Wellspring due to how ASP.NET manages the lifetime of objects post-request, there's whole libraries to manage that (like Hangfire). I wouldn't recommend just sending a task out in that kind of scenario

    – BradleyDotNET
    Dec 11 '18 at 20:40



















17














To me it seems that "awaiting" something and "fire and forget" are two orthogonal concepts. You either start a method asynchronously and don't care for the result, or you want to resume executing on the original context after the operation has finished (and possibly use a return value), which is exactly what await does. If you just want to execute a method on a ThreadPool thread (so that your UI doesn't get blocked), go for



Task.Factory.StartNew(() => DoIt2("Test2"))


and you'll be fine.






share|improve this answer



















  • 2





    the more I experiment with it the more it seems so. async is just for processes where you have meaningful continuation on the results from asynchronous task. No continuation need, no support (other than Task.Yield()). I guess I got sniped by marketing again...

    – mmix
    Oct 9 '12 at 15:34













  • When on subject, any real differences between delegate.BeginInvoke and Task.Factory.StartNew?

    – mmix
    Oct 9 '12 at 15:35






  • 1





    @mmix, the biggest difference with using Task is that if an exception occurs in the Task, it will wind up being thrown in the finalizer of the Task object, since there is nothing observing the faulted state of the Task. If you don't register for the TaskScheduler.UnobservedTaskException event, this can potentially cause a nasty crash without triggering your usual last-resort logging methods. It also has the unfortunate side effect of not crashing until GC causes the finalizer to run, whereas an invoked delegate will crash the app immediately after the exception.

    – Dan Bryant
    Oct 9 '12 at 15:56








  • 6





    @DanBryant: This has changed in .NET 4.5. UnobservedTaskException will no longer crash the process; if you don't handle it, the exceptions are silently ignored.

    – Stephen Cleary
    Oct 9 '12 at 16:11






  • 1





    I felt the same way at first; it took me a long time to come around to appreciating that design. Task-based code in the future will be async-based; in this new world, an unobserved Task is a fire-and-forget Task. This doesn't violate the fail-fast philosophy any more than the old behavior. The old behavior would crash by default because some error happened some indeterminate time before, so the old behavior wasn't "fail-fast" anyway.

    – Stephen Cleary
    Oct 9 '12 at 17:15



















1














My sense is that these 'fire and forget' methods were largely artifacts of needing a clean way to interleave UI and background code so that you can still write your logic as a series of sequential instructions. Since async/await takes care of marshalling through the SynchronizationContext, this becomes less of an issue. The inline code in a longer sequence effectively becomes your 'fire and forget' blocks that would previously have been launched from a routine in a background thread. It's effectively an inversion of the pattern.



The main difference is that the blocks between awaits are more akin to Invoke than BeginInvoke. If you need behavior more like BeginInvoke, you can call the next asynchronous method (returning a Task), then don't actually await the returned Task until after the code that you wanted to 'BeginInvoke'.



    public async void Method()
{
//Do UI stuff
await SomeTaskAsync();
//Do more UI stuff (as if called via Invoke from a thread)
var nextTask = NextTaskAsync();
//Do UI stuff while task is running (as if called via BeginInvoke from a thread)
await nextTask;
}





share|improve this answer



















  • 3





    Actually we use F&F to avoid blocking the http caller and it has more to do with caller limitations than our own. The logic is sound because caller does not expect a response other than message received (the actual process response will be posted on another channel unrelated to this, or http for that matter).

    – mmix
    Oct 9 '12 at 15:30











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f12803012%2ffire-and-forget-with-async-vs-old-async-delegate%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























4 Answers
4






active

oldest

votes








4 Answers
4






active

oldest

votes









active

oldest

votes






active

oldest

votes









72














Avoid async void. It has tricky semantics around error handling; I know some people call it "fire and forget" but I usually use the phrase "fire and crash".




The question is: Given a synchronous method A(), how can I call it asynchronously using async/await in a fire-and-forget manner without getting a solution that is more complicated than the "old way"




You don't need async / await. Just call it like this:



Task.Run(A);





share|improve this answer



















  • 4





    what if A() has async method calls in it?

    – Anthony Johnston
    Jan 26 '13 at 11:32






  • 2





    I mean, how do you avoid the warnings about not awaiting a task?

    – Anthony Johnston
    Jan 26 '13 at 11:40








  • 13





    That warning is there because fire-and-forget in an async method is almost certainly a mistake. If you're positively sure that's what you want to do, you can assign the result to an unused local variable like this: var _ = Task.Run(A);

    – Stephen Cleary
    Jan 26 '13 at 14:12











  • Thanks Stephen, and, yes, fire and forget is what I want, its a socket accept loop, async void seems perfect. Given that the method always properly handles exceptions (jaylee.org/post/2012/07/08/…) would you agree or am I just going to get in a pickle?

    – Anthony Johnston
    Jan 26 '13 at 15:03






  • 4





    @AnthonyJohnston: I meant calling a fire-and-forget method from an async method is almost certainly a mistake. In your case, since you always handle exceptions within the method, there's little difference between async Task and async void. I would still lean a bit more towards async Task, just because async void to me implies "event handler".

    – Stephen Cleary
    Jan 26 '13 at 15:52
















72














Avoid async void. It has tricky semantics around error handling; I know some people call it "fire and forget" but I usually use the phrase "fire and crash".




The question is: Given a synchronous method A(), how can I call it asynchronously using async/await in a fire-and-forget manner without getting a solution that is more complicated than the "old way"




You don't need async / await. Just call it like this:



Task.Run(A);





share|improve this answer



















  • 4





    what if A() has async method calls in it?

    – Anthony Johnston
    Jan 26 '13 at 11:32






  • 2





    I mean, how do you avoid the warnings about not awaiting a task?

    – Anthony Johnston
    Jan 26 '13 at 11:40








  • 13





    That warning is there because fire-and-forget in an async method is almost certainly a mistake. If you're positively sure that's what you want to do, you can assign the result to an unused local variable like this: var _ = Task.Run(A);

    – Stephen Cleary
    Jan 26 '13 at 14:12











  • Thanks Stephen, and, yes, fire and forget is what I want, its a socket accept loop, async void seems perfect. Given that the method always properly handles exceptions (jaylee.org/post/2012/07/08/…) would you agree or am I just going to get in a pickle?

    – Anthony Johnston
    Jan 26 '13 at 15:03






  • 4





    @AnthonyJohnston: I meant calling a fire-and-forget method from an async method is almost certainly a mistake. In your case, since you always handle exceptions within the method, there's little difference between async Task and async void. I would still lean a bit more towards async Task, just because async void to me implies "event handler".

    – Stephen Cleary
    Jan 26 '13 at 15:52














72












72








72







Avoid async void. It has tricky semantics around error handling; I know some people call it "fire and forget" but I usually use the phrase "fire and crash".




The question is: Given a synchronous method A(), how can I call it asynchronously using async/await in a fire-and-forget manner without getting a solution that is more complicated than the "old way"




You don't need async / await. Just call it like this:



Task.Run(A);





share|improve this answer













Avoid async void. It has tricky semantics around error handling; I know some people call it "fire and forget" but I usually use the phrase "fire and crash".




The question is: Given a synchronous method A(), how can I call it asynchronously using async/await in a fire-and-forget manner without getting a solution that is more complicated than the "old way"




You don't need async / await. Just call it like this:



Task.Run(A);






share|improve this answer












share|improve this answer



share|improve this answer










answered Oct 9 '12 at 16:06









Stephen ClearyStephen Cleary

277k46462585




277k46462585








  • 4





    what if A() has async method calls in it?

    – Anthony Johnston
    Jan 26 '13 at 11:32






  • 2





    I mean, how do you avoid the warnings about not awaiting a task?

    – Anthony Johnston
    Jan 26 '13 at 11:40








  • 13





    That warning is there because fire-and-forget in an async method is almost certainly a mistake. If you're positively sure that's what you want to do, you can assign the result to an unused local variable like this: var _ = Task.Run(A);

    – Stephen Cleary
    Jan 26 '13 at 14:12











  • Thanks Stephen, and, yes, fire and forget is what I want, its a socket accept loop, async void seems perfect. Given that the method always properly handles exceptions (jaylee.org/post/2012/07/08/…) would you agree or am I just going to get in a pickle?

    – Anthony Johnston
    Jan 26 '13 at 15:03






  • 4





    @AnthonyJohnston: I meant calling a fire-and-forget method from an async method is almost certainly a mistake. In your case, since you always handle exceptions within the method, there's little difference between async Task and async void. I would still lean a bit more towards async Task, just because async void to me implies "event handler".

    – Stephen Cleary
    Jan 26 '13 at 15:52














  • 4





    what if A() has async method calls in it?

    – Anthony Johnston
    Jan 26 '13 at 11:32






  • 2





    I mean, how do you avoid the warnings about not awaiting a task?

    – Anthony Johnston
    Jan 26 '13 at 11:40








  • 13





    That warning is there because fire-and-forget in an async method is almost certainly a mistake. If you're positively sure that's what you want to do, you can assign the result to an unused local variable like this: var _ = Task.Run(A);

    – Stephen Cleary
    Jan 26 '13 at 14:12











  • Thanks Stephen, and, yes, fire and forget is what I want, its a socket accept loop, async void seems perfect. Given that the method always properly handles exceptions (jaylee.org/post/2012/07/08/…) would you agree or am I just going to get in a pickle?

    – Anthony Johnston
    Jan 26 '13 at 15:03






  • 4





    @AnthonyJohnston: I meant calling a fire-and-forget method from an async method is almost certainly a mistake. In your case, since you always handle exceptions within the method, there's little difference between async Task and async void. I would still lean a bit more towards async Task, just because async void to me implies "event handler".

    – Stephen Cleary
    Jan 26 '13 at 15:52








4




4





what if A() has async method calls in it?

– Anthony Johnston
Jan 26 '13 at 11:32





what if A() has async method calls in it?

– Anthony Johnston
Jan 26 '13 at 11:32




2




2





I mean, how do you avoid the warnings about not awaiting a task?

– Anthony Johnston
Jan 26 '13 at 11:40







I mean, how do you avoid the warnings about not awaiting a task?

– Anthony Johnston
Jan 26 '13 at 11:40






13




13





That warning is there because fire-and-forget in an async method is almost certainly a mistake. If you're positively sure that's what you want to do, you can assign the result to an unused local variable like this: var _ = Task.Run(A);

– Stephen Cleary
Jan 26 '13 at 14:12





That warning is there because fire-and-forget in an async method is almost certainly a mistake. If you're positively sure that's what you want to do, you can assign the result to an unused local variable like this: var _ = Task.Run(A);

– Stephen Cleary
Jan 26 '13 at 14:12













Thanks Stephen, and, yes, fire and forget is what I want, its a socket accept loop, async void seems perfect. Given that the method always properly handles exceptions (jaylee.org/post/2012/07/08/…) would you agree or am I just going to get in a pickle?

– Anthony Johnston
Jan 26 '13 at 15:03





Thanks Stephen, and, yes, fire and forget is what I want, its a socket accept loop, async void seems perfect. Given that the method always properly handles exceptions (jaylee.org/post/2012/07/08/…) would you agree or am I just going to get in a pickle?

– Anthony Johnston
Jan 26 '13 at 15:03




4




4





@AnthonyJohnston: I meant calling a fire-and-forget method from an async method is almost certainly a mistake. In your case, since you always handle exceptions within the method, there's little difference between async Task and async void. I would still lean a bit more towards async Task, just because async void to me implies "event handler".

– Stephen Cleary
Jan 26 '13 at 15:52





@AnthonyJohnston: I meant calling a fire-and-forget method from an async method is almost certainly a mistake. In your case, since you always handle exceptions within the method, there's little difference between async Task and async void. I would still lean a bit more towards async Task, just because async void to me implies "event handler".

– Stephen Cleary
Jan 26 '13 at 15:52













39














As noted in the other answers, and by this excellent blog post you want to avoid using async void outside of UI event handlers. If you want a safe "fire and forget" async method, consider using this pattern (credit to @ReedCopsey; this method is one he gave to me in a chat conversation):





  1. Create an extension method for Task. It runs the passed Task and catches/logs any exceptions:



    static async void FireAndForget(this Task task)
    {
    try
    {
    await task;
    }
    catch (Exception e)
    {
    // log errors
    }
    }


  2. Always use Task style async methods when creating them, never async void.



  3. Invoke those methods this way:



    MyTaskAsyncMethod().FireAndForget();



You don't need to await it (nor will it generate the await warning). It will also handle any errors correctly, and as this is the only place you ever put async void, you don't have to remember to put try/catch blocks everywhere.



This also gives you the option of not using the async method as a "fire and forget" method if you actually want to await it normally.






share|improve this answer





















  • 2





    Well, if I have a Task, I'll just Run it, no?

    – mmix
    Jan 12 '15 at 16:13






  • 2





    @mmix That depends, you could use a Task object and run it, but thats not using await/async. This is how you do "fire and forget" with await/async. Note that this is much more useful when you are invoking Async framework methods, and you want to use them in a "fire and forget" sort of way.

    – BradleyDotNET
    Jan 12 '15 at 17:07






  • 2





    Hi, its an old post, but generally the idea was to use language "flow" elements to achieve fire and forget, without implicitly using Task object as such. WE came to a conclusion that its not possible since calling async does not raise new thread until it awaits. If I have Task object then I just Run()-it and it will fire and forget.

    – mmix
    Jan 18 '15 at 10:58











  • @mmix No problem, this just came up in a discussion I had with Reed Copsey, and in a separate question we had a discussion about using async void to do fire-and-forget where I was pointed to this question as to why not to do that. I was adding this as the "correct" way to utilize async void to do that.

    – BradleyDotNET
    Jan 18 '15 at 18:33








  • 1





    @Wellspring due to how ASP.NET manages the lifetime of objects post-request, there's whole libraries to manage that (like Hangfire). I wouldn't recommend just sending a task out in that kind of scenario

    – BradleyDotNET
    Dec 11 '18 at 20:40
















39














As noted in the other answers, and by this excellent blog post you want to avoid using async void outside of UI event handlers. If you want a safe "fire and forget" async method, consider using this pattern (credit to @ReedCopsey; this method is one he gave to me in a chat conversation):





  1. Create an extension method for Task. It runs the passed Task and catches/logs any exceptions:



    static async void FireAndForget(this Task task)
    {
    try
    {
    await task;
    }
    catch (Exception e)
    {
    // log errors
    }
    }


  2. Always use Task style async methods when creating them, never async void.



  3. Invoke those methods this way:



    MyTaskAsyncMethod().FireAndForget();



You don't need to await it (nor will it generate the await warning). It will also handle any errors correctly, and as this is the only place you ever put async void, you don't have to remember to put try/catch blocks everywhere.



This also gives you the option of not using the async method as a "fire and forget" method if you actually want to await it normally.






share|improve this answer





















  • 2





    Well, if I have a Task, I'll just Run it, no?

    – mmix
    Jan 12 '15 at 16:13






  • 2





    @mmix That depends, you could use a Task object and run it, but thats not using await/async. This is how you do "fire and forget" with await/async. Note that this is much more useful when you are invoking Async framework methods, and you want to use them in a "fire and forget" sort of way.

    – BradleyDotNET
    Jan 12 '15 at 17:07






  • 2





    Hi, its an old post, but generally the idea was to use language "flow" elements to achieve fire and forget, without implicitly using Task object as such. WE came to a conclusion that its not possible since calling async does not raise new thread until it awaits. If I have Task object then I just Run()-it and it will fire and forget.

    – mmix
    Jan 18 '15 at 10:58











  • @mmix No problem, this just came up in a discussion I had with Reed Copsey, and in a separate question we had a discussion about using async void to do fire-and-forget where I was pointed to this question as to why not to do that. I was adding this as the "correct" way to utilize async void to do that.

    – BradleyDotNET
    Jan 18 '15 at 18:33








  • 1





    @Wellspring due to how ASP.NET manages the lifetime of objects post-request, there's whole libraries to manage that (like Hangfire). I wouldn't recommend just sending a task out in that kind of scenario

    – BradleyDotNET
    Dec 11 '18 at 20:40














39












39








39







As noted in the other answers, and by this excellent blog post you want to avoid using async void outside of UI event handlers. If you want a safe "fire and forget" async method, consider using this pattern (credit to @ReedCopsey; this method is one he gave to me in a chat conversation):





  1. Create an extension method for Task. It runs the passed Task and catches/logs any exceptions:



    static async void FireAndForget(this Task task)
    {
    try
    {
    await task;
    }
    catch (Exception e)
    {
    // log errors
    }
    }


  2. Always use Task style async methods when creating them, never async void.



  3. Invoke those methods this way:



    MyTaskAsyncMethod().FireAndForget();



You don't need to await it (nor will it generate the await warning). It will also handle any errors correctly, and as this is the only place you ever put async void, you don't have to remember to put try/catch blocks everywhere.



This also gives you the option of not using the async method as a "fire and forget" method if you actually want to await it normally.






share|improve this answer















As noted in the other answers, and by this excellent blog post you want to avoid using async void outside of UI event handlers. If you want a safe "fire and forget" async method, consider using this pattern (credit to @ReedCopsey; this method is one he gave to me in a chat conversation):





  1. Create an extension method for Task. It runs the passed Task and catches/logs any exceptions:



    static async void FireAndForget(this Task task)
    {
    try
    {
    await task;
    }
    catch (Exception e)
    {
    // log errors
    }
    }


  2. Always use Task style async methods when creating them, never async void.



  3. Invoke those methods this way:



    MyTaskAsyncMethod().FireAndForget();



You don't need to await it (nor will it generate the await warning). It will also handle any errors correctly, and as this is the only place you ever put async void, you don't have to remember to put try/catch blocks everywhere.



This also gives you the option of not using the async method as a "fire and forget" method if you actually want to await it normally.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 9 '15 at 1:24

























answered Jan 9 '15 at 1:19









BradleyDotNETBradleyDotNET

51.5k86889




51.5k86889








  • 2





    Well, if I have a Task, I'll just Run it, no?

    – mmix
    Jan 12 '15 at 16:13






  • 2





    @mmix That depends, you could use a Task object and run it, but thats not using await/async. This is how you do "fire and forget" with await/async. Note that this is much more useful when you are invoking Async framework methods, and you want to use them in a "fire and forget" sort of way.

    – BradleyDotNET
    Jan 12 '15 at 17:07






  • 2





    Hi, its an old post, but generally the idea was to use language "flow" elements to achieve fire and forget, without implicitly using Task object as such. WE came to a conclusion that its not possible since calling async does not raise new thread until it awaits. If I have Task object then I just Run()-it and it will fire and forget.

    – mmix
    Jan 18 '15 at 10:58











  • @mmix No problem, this just came up in a discussion I had with Reed Copsey, and in a separate question we had a discussion about using async void to do fire-and-forget where I was pointed to this question as to why not to do that. I was adding this as the "correct" way to utilize async void to do that.

    – BradleyDotNET
    Jan 18 '15 at 18:33








  • 1





    @Wellspring due to how ASP.NET manages the lifetime of objects post-request, there's whole libraries to manage that (like Hangfire). I wouldn't recommend just sending a task out in that kind of scenario

    – BradleyDotNET
    Dec 11 '18 at 20:40














  • 2





    Well, if I have a Task, I'll just Run it, no?

    – mmix
    Jan 12 '15 at 16:13






  • 2





    @mmix That depends, you could use a Task object and run it, but thats not using await/async. This is how you do "fire and forget" with await/async. Note that this is much more useful when you are invoking Async framework methods, and you want to use them in a "fire and forget" sort of way.

    – BradleyDotNET
    Jan 12 '15 at 17:07






  • 2





    Hi, its an old post, but generally the idea was to use language "flow" elements to achieve fire and forget, without implicitly using Task object as such. WE came to a conclusion that its not possible since calling async does not raise new thread until it awaits. If I have Task object then I just Run()-it and it will fire and forget.

    – mmix
    Jan 18 '15 at 10:58











  • @mmix No problem, this just came up in a discussion I had with Reed Copsey, and in a separate question we had a discussion about using async void to do fire-and-forget where I was pointed to this question as to why not to do that. I was adding this as the "correct" way to utilize async void to do that.

    – BradleyDotNET
    Jan 18 '15 at 18:33








  • 1





    @Wellspring due to how ASP.NET manages the lifetime of objects post-request, there's whole libraries to manage that (like Hangfire). I wouldn't recommend just sending a task out in that kind of scenario

    – BradleyDotNET
    Dec 11 '18 at 20:40








2




2





Well, if I have a Task, I'll just Run it, no?

– mmix
Jan 12 '15 at 16:13





Well, if I have a Task, I'll just Run it, no?

– mmix
Jan 12 '15 at 16:13




2




2





@mmix That depends, you could use a Task object and run it, but thats not using await/async. This is how you do "fire and forget" with await/async. Note that this is much more useful when you are invoking Async framework methods, and you want to use them in a "fire and forget" sort of way.

– BradleyDotNET
Jan 12 '15 at 17:07





@mmix That depends, you could use a Task object and run it, but thats not using await/async. This is how you do "fire and forget" with await/async. Note that this is much more useful when you are invoking Async framework methods, and you want to use them in a "fire and forget" sort of way.

– BradleyDotNET
Jan 12 '15 at 17:07




2




2





Hi, its an old post, but generally the idea was to use language "flow" elements to achieve fire and forget, without implicitly using Task object as such. WE came to a conclusion that its not possible since calling async does not raise new thread until it awaits. If I have Task object then I just Run()-it and it will fire and forget.

– mmix
Jan 18 '15 at 10:58





Hi, its an old post, but generally the idea was to use language "flow" elements to achieve fire and forget, without implicitly using Task object as such. WE came to a conclusion that its not possible since calling async does not raise new thread until it awaits. If I have Task object then I just Run()-it and it will fire and forget.

– mmix
Jan 18 '15 at 10:58













@mmix No problem, this just came up in a discussion I had with Reed Copsey, and in a separate question we had a discussion about using async void to do fire-and-forget where I was pointed to this question as to why not to do that. I was adding this as the "correct" way to utilize async void to do that.

– BradleyDotNET
Jan 18 '15 at 18:33







@mmix No problem, this just came up in a discussion I had with Reed Copsey, and in a separate question we had a discussion about using async void to do fire-and-forget where I was pointed to this question as to why not to do that. I was adding this as the "correct" way to utilize async void to do that.

– BradleyDotNET
Jan 18 '15 at 18:33






1




1





@Wellspring due to how ASP.NET manages the lifetime of objects post-request, there's whole libraries to manage that (like Hangfire). I wouldn't recommend just sending a task out in that kind of scenario

– BradleyDotNET
Dec 11 '18 at 20:40





@Wellspring due to how ASP.NET manages the lifetime of objects post-request, there's whole libraries to manage that (like Hangfire). I wouldn't recommend just sending a task out in that kind of scenario

– BradleyDotNET
Dec 11 '18 at 20:40











17














To me it seems that "awaiting" something and "fire and forget" are two orthogonal concepts. You either start a method asynchronously and don't care for the result, or you want to resume executing on the original context after the operation has finished (and possibly use a return value), which is exactly what await does. If you just want to execute a method on a ThreadPool thread (so that your UI doesn't get blocked), go for



Task.Factory.StartNew(() => DoIt2("Test2"))


and you'll be fine.






share|improve this answer



















  • 2





    the more I experiment with it the more it seems so. async is just for processes where you have meaningful continuation on the results from asynchronous task. No continuation need, no support (other than Task.Yield()). I guess I got sniped by marketing again...

    – mmix
    Oct 9 '12 at 15:34













  • When on subject, any real differences between delegate.BeginInvoke and Task.Factory.StartNew?

    – mmix
    Oct 9 '12 at 15:35






  • 1





    @mmix, the biggest difference with using Task is that if an exception occurs in the Task, it will wind up being thrown in the finalizer of the Task object, since there is nothing observing the faulted state of the Task. If you don't register for the TaskScheduler.UnobservedTaskException event, this can potentially cause a nasty crash without triggering your usual last-resort logging methods. It also has the unfortunate side effect of not crashing until GC causes the finalizer to run, whereas an invoked delegate will crash the app immediately after the exception.

    – Dan Bryant
    Oct 9 '12 at 15:56








  • 6





    @DanBryant: This has changed in .NET 4.5. UnobservedTaskException will no longer crash the process; if you don't handle it, the exceptions are silently ignored.

    – Stephen Cleary
    Oct 9 '12 at 16:11






  • 1





    I felt the same way at first; it took me a long time to come around to appreciating that design. Task-based code in the future will be async-based; in this new world, an unobserved Task is a fire-and-forget Task. This doesn't violate the fail-fast philosophy any more than the old behavior. The old behavior would crash by default because some error happened some indeterminate time before, so the old behavior wasn't "fail-fast" anyway.

    – Stephen Cleary
    Oct 9 '12 at 17:15
















17














To me it seems that "awaiting" something and "fire and forget" are two orthogonal concepts. You either start a method asynchronously and don't care for the result, or you want to resume executing on the original context after the operation has finished (and possibly use a return value), which is exactly what await does. If you just want to execute a method on a ThreadPool thread (so that your UI doesn't get blocked), go for



Task.Factory.StartNew(() => DoIt2("Test2"))


and you'll be fine.






share|improve this answer



















  • 2





    the more I experiment with it the more it seems so. async is just for processes where you have meaningful continuation on the results from asynchronous task. No continuation need, no support (other than Task.Yield()). I guess I got sniped by marketing again...

    – mmix
    Oct 9 '12 at 15:34













  • When on subject, any real differences between delegate.BeginInvoke and Task.Factory.StartNew?

    – mmix
    Oct 9 '12 at 15:35






  • 1





    @mmix, the biggest difference with using Task is that if an exception occurs in the Task, it will wind up being thrown in the finalizer of the Task object, since there is nothing observing the faulted state of the Task. If you don't register for the TaskScheduler.UnobservedTaskException event, this can potentially cause a nasty crash without triggering your usual last-resort logging methods. It also has the unfortunate side effect of not crashing until GC causes the finalizer to run, whereas an invoked delegate will crash the app immediately after the exception.

    – Dan Bryant
    Oct 9 '12 at 15:56








  • 6





    @DanBryant: This has changed in .NET 4.5. UnobservedTaskException will no longer crash the process; if you don't handle it, the exceptions are silently ignored.

    – Stephen Cleary
    Oct 9 '12 at 16:11






  • 1





    I felt the same way at first; it took me a long time to come around to appreciating that design. Task-based code in the future will be async-based; in this new world, an unobserved Task is a fire-and-forget Task. This doesn't violate the fail-fast philosophy any more than the old behavior. The old behavior would crash by default because some error happened some indeterminate time before, so the old behavior wasn't "fail-fast" anyway.

    – Stephen Cleary
    Oct 9 '12 at 17:15














17












17








17







To me it seems that "awaiting" something and "fire and forget" are two orthogonal concepts. You either start a method asynchronously and don't care for the result, or you want to resume executing on the original context after the operation has finished (and possibly use a return value), which is exactly what await does. If you just want to execute a method on a ThreadPool thread (so that your UI doesn't get blocked), go for



Task.Factory.StartNew(() => DoIt2("Test2"))


and you'll be fine.






share|improve this answer













To me it seems that "awaiting" something and "fire and forget" are two orthogonal concepts. You either start a method asynchronously and don't care for the result, or you want to resume executing on the original context after the operation has finished (and possibly use a return value), which is exactly what await does. If you just want to execute a method on a ThreadPool thread (so that your UI doesn't get blocked), go for



Task.Factory.StartNew(() => DoIt2("Test2"))


and you'll be fine.







share|improve this answer












share|improve this answer



share|improve this answer










answered Oct 9 '12 at 15:26









Daniel C. WeberDaniel C. Weber

751311




751311








  • 2





    the more I experiment with it the more it seems so. async is just for processes where you have meaningful continuation on the results from asynchronous task. No continuation need, no support (other than Task.Yield()). I guess I got sniped by marketing again...

    – mmix
    Oct 9 '12 at 15:34













  • When on subject, any real differences between delegate.BeginInvoke and Task.Factory.StartNew?

    – mmix
    Oct 9 '12 at 15:35






  • 1





    @mmix, the biggest difference with using Task is that if an exception occurs in the Task, it will wind up being thrown in the finalizer of the Task object, since there is nothing observing the faulted state of the Task. If you don't register for the TaskScheduler.UnobservedTaskException event, this can potentially cause a nasty crash without triggering your usual last-resort logging methods. It also has the unfortunate side effect of not crashing until GC causes the finalizer to run, whereas an invoked delegate will crash the app immediately after the exception.

    – Dan Bryant
    Oct 9 '12 at 15:56








  • 6





    @DanBryant: This has changed in .NET 4.5. UnobservedTaskException will no longer crash the process; if you don't handle it, the exceptions are silently ignored.

    – Stephen Cleary
    Oct 9 '12 at 16:11






  • 1





    I felt the same way at first; it took me a long time to come around to appreciating that design. Task-based code in the future will be async-based; in this new world, an unobserved Task is a fire-and-forget Task. This doesn't violate the fail-fast philosophy any more than the old behavior. The old behavior would crash by default because some error happened some indeterminate time before, so the old behavior wasn't "fail-fast" anyway.

    – Stephen Cleary
    Oct 9 '12 at 17:15














  • 2





    the more I experiment with it the more it seems so. async is just for processes where you have meaningful continuation on the results from asynchronous task. No continuation need, no support (other than Task.Yield()). I guess I got sniped by marketing again...

    – mmix
    Oct 9 '12 at 15:34













  • When on subject, any real differences between delegate.BeginInvoke and Task.Factory.StartNew?

    – mmix
    Oct 9 '12 at 15:35






  • 1





    @mmix, the biggest difference with using Task is that if an exception occurs in the Task, it will wind up being thrown in the finalizer of the Task object, since there is nothing observing the faulted state of the Task. If you don't register for the TaskScheduler.UnobservedTaskException event, this can potentially cause a nasty crash without triggering your usual last-resort logging methods. It also has the unfortunate side effect of not crashing until GC causes the finalizer to run, whereas an invoked delegate will crash the app immediately after the exception.

    – Dan Bryant
    Oct 9 '12 at 15:56








  • 6





    @DanBryant: This has changed in .NET 4.5. UnobservedTaskException will no longer crash the process; if you don't handle it, the exceptions are silently ignored.

    – Stephen Cleary
    Oct 9 '12 at 16:11






  • 1





    I felt the same way at first; it took me a long time to come around to appreciating that design. Task-based code in the future will be async-based; in this new world, an unobserved Task is a fire-and-forget Task. This doesn't violate the fail-fast philosophy any more than the old behavior. The old behavior would crash by default because some error happened some indeterminate time before, so the old behavior wasn't "fail-fast" anyway.

    – Stephen Cleary
    Oct 9 '12 at 17:15








2




2





the more I experiment with it the more it seems so. async is just for processes where you have meaningful continuation on the results from asynchronous task. No continuation need, no support (other than Task.Yield()). I guess I got sniped by marketing again...

– mmix
Oct 9 '12 at 15:34







the more I experiment with it the more it seems so. async is just for processes where you have meaningful continuation on the results from asynchronous task. No continuation need, no support (other than Task.Yield()). I guess I got sniped by marketing again...

– mmix
Oct 9 '12 at 15:34















When on subject, any real differences between delegate.BeginInvoke and Task.Factory.StartNew?

– mmix
Oct 9 '12 at 15:35





When on subject, any real differences between delegate.BeginInvoke and Task.Factory.StartNew?

– mmix
Oct 9 '12 at 15:35




1




1





@mmix, the biggest difference with using Task is that if an exception occurs in the Task, it will wind up being thrown in the finalizer of the Task object, since there is nothing observing the faulted state of the Task. If you don't register for the TaskScheduler.UnobservedTaskException event, this can potentially cause a nasty crash without triggering your usual last-resort logging methods. It also has the unfortunate side effect of not crashing until GC causes the finalizer to run, whereas an invoked delegate will crash the app immediately after the exception.

– Dan Bryant
Oct 9 '12 at 15:56







@mmix, the biggest difference with using Task is that if an exception occurs in the Task, it will wind up being thrown in the finalizer of the Task object, since there is nothing observing the faulted state of the Task. If you don't register for the TaskScheduler.UnobservedTaskException event, this can potentially cause a nasty crash without triggering your usual last-resort logging methods. It also has the unfortunate side effect of not crashing until GC causes the finalizer to run, whereas an invoked delegate will crash the app immediately after the exception.

– Dan Bryant
Oct 9 '12 at 15:56






6




6





@DanBryant: This has changed in .NET 4.5. UnobservedTaskException will no longer crash the process; if you don't handle it, the exceptions are silently ignored.

– Stephen Cleary
Oct 9 '12 at 16:11





@DanBryant: This has changed in .NET 4.5. UnobservedTaskException will no longer crash the process; if you don't handle it, the exceptions are silently ignored.

– Stephen Cleary
Oct 9 '12 at 16:11




1




1





I felt the same way at first; it took me a long time to come around to appreciating that design. Task-based code in the future will be async-based; in this new world, an unobserved Task is a fire-and-forget Task. This doesn't violate the fail-fast philosophy any more than the old behavior. The old behavior would crash by default because some error happened some indeterminate time before, so the old behavior wasn't "fail-fast" anyway.

– Stephen Cleary
Oct 9 '12 at 17:15





I felt the same way at first; it took me a long time to come around to appreciating that design. Task-based code in the future will be async-based; in this new world, an unobserved Task is a fire-and-forget Task. This doesn't violate the fail-fast philosophy any more than the old behavior. The old behavior would crash by default because some error happened some indeterminate time before, so the old behavior wasn't "fail-fast" anyway.

– Stephen Cleary
Oct 9 '12 at 17:15











1














My sense is that these 'fire and forget' methods were largely artifacts of needing a clean way to interleave UI and background code so that you can still write your logic as a series of sequential instructions. Since async/await takes care of marshalling through the SynchronizationContext, this becomes less of an issue. The inline code in a longer sequence effectively becomes your 'fire and forget' blocks that would previously have been launched from a routine in a background thread. It's effectively an inversion of the pattern.



The main difference is that the blocks between awaits are more akin to Invoke than BeginInvoke. If you need behavior more like BeginInvoke, you can call the next asynchronous method (returning a Task), then don't actually await the returned Task until after the code that you wanted to 'BeginInvoke'.



    public async void Method()
{
//Do UI stuff
await SomeTaskAsync();
//Do more UI stuff (as if called via Invoke from a thread)
var nextTask = NextTaskAsync();
//Do UI stuff while task is running (as if called via BeginInvoke from a thread)
await nextTask;
}





share|improve this answer



















  • 3





    Actually we use F&F to avoid blocking the http caller and it has more to do with caller limitations than our own. The logic is sound because caller does not expect a response other than message received (the actual process response will be posted on another channel unrelated to this, or http for that matter).

    – mmix
    Oct 9 '12 at 15:30
















1














My sense is that these 'fire and forget' methods were largely artifacts of needing a clean way to interleave UI and background code so that you can still write your logic as a series of sequential instructions. Since async/await takes care of marshalling through the SynchronizationContext, this becomes less of an issue. The inline code in a longer sequence effectively becomes your 'fire and forget' blocks that would previously have been launched from a routine in a background thread. It's effectively an inversion of the pattern.



The main difference is that the blocks between awaits are more akin to Invoke than BeginInvoke. If you need behavior more like BeginInvoke, you can call the next asynchronous method (returning a Task), then don't actually await the returned Task until after the code that you wanted to 'BeginInvoke'.



    public async void Method()
{
//Do UI stuff
await SomeTaskAsync();
//Do more UI stuff (as if called via Invoke from a thread)
var nextTask = NextTaskAsync();
//Do UI stuff while task is running (as if called via BeginInvoke from a thread)
await nextTask;
}





share|improve this answer



















  • 3





    Actually we use F&F to avoid blocking the http caller and it has more to do with caller limitations than our own. The logic is sound because caller does not expect a response other than message received (the actual process response will be posted on another channel unrelated to this, or http for that matter).

    – mmix
    Oct 9 '12 at 15:30














1












1








1







My sense is that these 'fire and forget' methods were largely artifacts of needing a clean way to interleave UI and background code so that you can still write your logic as a series of sequential instructions. Since async/await takes care of marshalling through the SynchronizationContext, this becomes less of an issue. The inline code in a longer sequence effectively becomes your 'fire and forget' blocks that would previously have been launched from a routine in a background thread. It's effectively an inversion of the pattern.



The main difference is that the blocks between awaits are more akin to Invoke than BeginInvoke. If you need behavior more like BeginInvoke, you can call the next asynchronous method (returning a Task), then don't actually await the returned Task until after the code that you wanted to 'BeginInvoke'.



    public async void Method()
{
//Do UI stuff
await SomeTaskAsync();
//Do more UI stuff (as if called via Invoke from a thread)
var nextTask = NextTaskAsync();
//Do UI stuff while task is running (as if called via BeginInvoke from a thread)
await nextTask;
}





share|improve this answer













My sense is that these 'fire and forget' methods were largely artifacts of needing a clean way to interleave UI and background code so that you can still write your logic as a series of sequential instructions. Since async/await takes care of marshalling through the SynchronizationContext, this becomes less of an issue. The inline code in a longer sequence effectively becomes your 'fire and forget' blocks that would previously have been launched from a routine in a background thread. It's effectively an inversion of the pattern.



The main difference is that the blocks between awaits are more akin to Invoke than BeginInvoke. If you need behavior more like BeginInvoke, you can call the next asynchronous method (returning a Task), then don't actually await the returned Task until after the code that you wanted to 'BeginInvoke'.



    public async void Method()
{
//Do UI stuff
await SomeTaskAsync();
//Do more UI stuff (as if called via Invoke from a thread)
var nextTask = NextTaskAsync();
//Do UI stuff while task is running (as if called via BeginInvoke from a thread)
await nextTask;
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Oct 9 '12 at 15:16









Dan BryantDan Bryant

24.1k34488




24.1k34488








  • 3





    Actually we use F&F to avoid blocking the http caller and it has more to do with caller limitations than our own. The logic is sound because caller does not expect a response other than message received (the actual process response will be posted on another channel unrelated to this, or http for that matter).

    – mmix
    Oct 9 '12 at 15:30














  • 3





    Actually we use F&F to avoid blocking the http caller and it has more to do with caller limitations than our own. The logic is sound because caller does not expect a response other than message received (the actual process response will be posted on another channel unrelated to this, or http for that matter).

    – mmix
    Oct 9 '12 at 15:30








3




3





Actually we use F&F to avoid blocking the http caller and it has more to do with caller limitations than our own. The logic is sound because caller does not expect a response other than message received (the actual process response will be posted on another channel unrelated to this, or http for that matter).

– mmix
Oct 9 '12 at 15:30





Actually we use F&F to avoid blocking the http caller and it has more to do with caller limitations than our own. The logic is sound because caller does not expect a response other than message received (the actual process response will be posted on another channel unrelated to this, or http for that matter).

– mmix
Oct 9 '12 at 15:30


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f12803012%2ffire-and-forget-with-async-vs-old-async-delegate%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Contact image not getting when fetch all contact list from iPhone by CNContact

count number of partitions of a set with n elements into k subsets

A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks