{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/13897","repository_url":"https://api.github.com/repos/dotnet/roslyn","labels_url":"https://api.github.com/repos/dotnet/roslyn/issues/13897/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/13897/comments","events_url":"https://api.github.com/repos/dotnet/roslyn/issues/13897/events","html_url":"https://github.com/dotnet/roslyn/issues/13897","id":177825218,"number":13897,"title":"Proposal: Deprecate async void","user":{"login":"tenor","id":526262,"avatar_url":"https://avatars1.githubusercontent.com/u/526262?v=3","gravatar_id":"","url":"https://api.github.com/users/tenor","html_url":"https://github.com/tenor","followers_url":"https://api.github.com/users/tenor/followers","following_url":"https://api.github.com/users/tenor/following{/other_user}","gists_url":"https://api.github.com/users/tenor/gists{/gist_id}","starred_url":"https://api.github.com/users/tenor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tenor/subscriptions","organizations_url":"https://api.github.com/users/tenor/orgs","repos_url":"https://api.github.com/users/tenor/repos","events_url":"https://api.github.com/users/tenor/events{/privacy}","received_events_url":"https://api.github.com/users/tenor/received_events","type":"User","site_admin":false},"labels":[{"id":169838071,"url":"https://api.github.com/repos/dotnet/roslyn/labels/Area-Language%20Design","name":"Area-Language Design","color":"5319e7","default":false},{"id":166377946,"url":"https://api.github.com/repos/dotnet/roslyn/labels/Language-C%23","name":"Language-C#","color":"207de5","default":false},{"id":166377961,"url":"https://api.github.com/repos/dotnet/roslyn/labels/Language-VB","name":"Language-VB","color":"207de5","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":30,"created_at":"2016-09-19T16:01:01Z","updated_at":"2017-03-02T14:27:26Z","closed_at":null,"body":"I propose that the `async void` C# and VB language constructs be deprecated, for the following reasons.\n\n**1. Its purpose can be achieved via other means**\n\nThe code below\n\n``` csharp\nasync void AsyncVoidMethod()\n{\n    //Do some work\n    await Task.Yield();\n    //Do some more work\n}\n\n//Call method\nAsyncVoidMethod();\n```\n\nis more or less the same as\n\n``` csharp\nasync Task AsyncVoidHelper(Action action)\n{\n    Action outerAction = () => {\n        SynchronizationContext.Current?.OperationStarted();\n        action();\n        SynchronizationContext.Current?.OperationCompleted();\n    };\n\n    await Task.Factory.StartNew(outerAction,\n        CancellationToken.None,\n        TaskCreationOptions.DenyChildAttach,\n        TaskScheduler.Current);\n}\n\nasync Task WorkMethod()\n{\n    //Do some work\n    await Task.Yield();\n    //Do some more work\n}\n\n//Call method\nAsyncVoidHelper(async () => await WorkMethod());\n```\n\n**2. async void is widely misunderstood**\nMany tutorials on the web describe `async void` as a _fire and forget_ feature but that's not completely accurate. async void methods can still block the caller if execution doesn't run into an `await` statement, and even then, it can still block the caller if the await call runs synchronously.\nThus, async void methods have inconsistent return semantics. It can (a) return immediately -- while the rest of the method is processed by another task/thread, (b) block for a while and return -- while the rest of the method is processed by another task/thread, or (c) block indefinitely. The caller has no way of knowing what to expect.\nIn actuality, `async void` methods when factored with its weird exception handling behavior (discussed next) is really a _fire and hope to forget_ feature.\n\n**3. async void can be disastrous**\nIf a developer unwittingly adds an `async` keyword to a `void` method, making the method an `async void` method. That developer has just added a time bomb to their application. Any exception that gets thrown in that method can take down the entire process. That exception cannot be caught by callers to the `async void` method.\nAlso note that this applies to any exception thrown by methods the `async void` method calls.\nThe code will still compile and run fine after the `void` to `async void` change and is small enough to easily slip through code review.\n\n**4. async void is too advanced to be a language level feature**\nFor anyone to use the `async void` feature safely, they have to be aware of its pitfalls and unique scenarios. It's the only language construct (that I'm aware of) that has a unique exception handling behavior, and that can stump even experienced developers.\n\nRemoval of this construct will make the language a little more safer. Asynchronous event handlers can still be written using a helper as illustrated in [1].\n"},"comment":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/comments/283667220","html_url":"https://github.com/dotnet/roslyn/issues/13897#issuecomment-283667220","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/13897","id":283667220,"user":{"login":"molinch","id":5130190,"avatar_url":"https://avatars1.githubusercontent.com/u/5130190?v=3","gravatar_id":"","url":"https://api.github.com/users/molinch","html_url":"https://github.com/molinch","followers_url":"https://api.github.com/users/molinch/followers","following_url":"https://api.github.com/users/molinch/following{/other_user}","gists_url":"https://api.github.com/users/molinch/gists{/gist_id}","starred_url":"https://api.github.com/users/molinch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/molinch/subscriptions","organizations_url":"https://api.github.com/users/molinch/orgs","repos_url":"https://api.github.com/users/molinch/repos","events_url":"https://api.github.com/users/molinch/events{/privacy}","received_events_url":"https://api.github.com/users/molinch/received_events","type":"User","site_admin":false},"created_at":"2017-03-02T14:27:26Z","updated_at":"2017-03-02T14:27:26Z","body":"Thanks @benaadams \r\nWill ```ContinueWith``` behave normally with Promises tasks?"}}
{"actor":{"display_login":"molinch"}}