{"action":"closed","issue":{"url":"https://api.github.com/repos/Reactive-Extensions/Rx.NET/issues/21","labels_url":"https://api.github.com/repos/Reactive-Extensions/Rx.NET/issues/21/labels{/name}","comments_url":"https://api.github.com/repos/Reactive-Extensions/Rx.NET/issues/21/comments","events_url":"https://api.github.com/repos/Reactive-Extensions/Rx.NET/issues/21/events","html_url":"https://github.com/Reactive-Extensions/Rx.NET/issues/21","id":45656619,"number":21,"title":"Bug: Task-Related Operator Overloads Introduce Concurrency","user":{"login":"mattpodwysocki","id":49051,"avatar_url":"https://avatars.githubusercontent.com/u/49051?v=3","gravatar_id":"","url":"https://api.github.com/users/mattpodwysocki","html_url":"https://github.com/mattpodwysocki","followers_url":"https://api.github.com/users/mattpodwysocki/followers","following_url":"https://api.github.com/users/mattpodwysocki/following{/other_user}","gists_url":"https://api.github.com/users/mattpodwysocki/gists{/gist_id}","starred_url":"https://api.github.com/users/mattpodwysocki/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mattpodwysocki/subscriptions","organizations_url":"https://api.github.com/users/mattpodwysocki/orgs","repos_url":"https://api.github.com/users/mattpodwysocki/repos","events_url":"https://api.github.com/users/mattpodwysocki/events{/privacy}","received_events_url":"https://api.github.com/users/mattpodwysocki/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2014-10-13T15:48:06Z","updated_at":"2015-04-25T01:35:28Z","closed_at":"2015-04-25T01:35:28Z","body":"Copied from https://rx.codeplex.com/workitem/48\r\n\r\nHi,\r\n\r\nI just ran into a problem related to the unexpected introduction of concurrency when using Task-based asynchrony in conjunction with Rx in a Windows 8 app.  I've had this problem before and thought that I was doing something wrong or that it's the correct behavior of some kind of new multi-threaded UI model in WinRT, yet now I realize that it seems to be a bug in Rx.\r\n\r\nIf you search the entire Rx codebase for \".ContinueWith(\" you'll see that every usage doesn't specify the [ExecuteSynchronously](http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskcontinuationoptions.aspx) flag, thus allowing the TPL to schedule the continuation on the thread pool, and it always does.\r\n\r\nAccording to the [documentation](http://msdn.microsoft.com/en-us/library/dd270696.aspx): \r\n\r\n> Creates a continuation that executes asynchronously when the target Task<TResult> completes.\r\n\r\nBut we don't want asynchronous execution, we want synchronous execution.  I'd imagine this is true for all uses of __ContinueWith__ throughout Rx, though I haven't looked at the finer details yet.\r\n\r\nExecuting __ContinueWith__ asynchronously is a problem in general because the concurrency being introduced isn't related to the specified IScheduler, if one is supplied by the user, and it's entirely unexpected when using particular operators that should never introduce concurrency by default, as shown below.  As a result, the threading context of notifications is incorrect and we have little control over it.\r\n\r\nThere are two situations in which I've run into this problem in my code: \r\n 1. The __ToObservable__ extension for __Task<T>__ always introduces concurrency.  For example, the following code illustrates how the UI threading context is automatically captured by _await_, since I'm not specifying `ConfigureAwait(false)`, yet it's lost with __ToObservable__.  My expectation has always been that the observable returned by __ToObservable__ simply generates a notification within the completion context of the converted __Task__, without introducing concurrency unnecessarily.  (NOTE: I'm not actually sure whether forcing Rx's usage of __ContinueWith__ to execute synchronously would solve this problem, though I expect that it will.)\r\n```c#\r\nprivate async void _Loaded(object sender, RoutedEventArgs e)\r\n{\r\n    Contract.Assert(Dispatcher.HasThreadAccess);  // true\r\n    await DoSomethingAsync();\r\n    Contract.Assert(Dispatcher.HasThreadAccess);  // true\r\n    DoSomethingAsync().ToObservable().Subscribe(_ =>\r\n    {\r\n        Contract.Assert(Dispatcher.HasThreadAccess);  // false!\r\n    });\r\n}\r\n\r\nprivate async Task DoSomethingAsync()\r\n{\r\n    await Task.Delay(TimeSpan.FromSeconds(1));\r\n\r\n    Contract.Assert(Dispatcher.HasThreadAccess);  // true\r\n}\r\n```\r\n 2. The overloads of __SelectMany__ that compose an observable with a __Task<T>__ incorrectly introduce concurrency.  This is even worse than the previous issue because if we don't realize that it's caused by Rx then we'll typically try to resolve the problem by composing another __SelectMany__ query that awaits some kind of dispatcher yield operation, but as it turns out if it's the same __Task__-related __SelectMany__ overload then the problem occurs again, though if it's an observable then it's likely that it was converted from a __Task__ via __ToObservable__, which as I've shown above is also flawed in this way, so the problem remains.  This is what led me to believe a while ago that it was an issue related to Windows 8 rather than Rx.  No matter what I did the query was always running outside of the UI thread.  __ObserveOnDispatcher__ doesn't even solve the problem (at least not in my particular situation).\r\n\r\nCan anyone else confirm that this behavior is indeed a bug?\r\n\r\nI'd be happy to fix it and have it ready in a day or two, before the next planned release hopefully, though it's also possibly a breaking change (for the better, I guess) so I'd like to get a green light from the Rx team before doing the work.\r\n\r\nThanks,\r\nDave"}}