Unexpected deadlock (partially-async WinRT)
-
lunes, 19 de diciembre de 2011 15:03
Regarding this SO question:
http://stackoverflow.com/questions/8554982/deserialization-and-async-await
I haven't had a chance to do a test case myself, but there's an unexpected deadlock happening there. It looks like a WinRT input stream read completion is marshaling back to the SyncContext - even though it's not awaited.
Could someone provide an explanation for this? As I understand it, WinRT completions should always go to the (WinRT) threadpool, and in this case should set the ManualResetEvent in the stream wrapper, allowing the operation to complete. The original code is doing a blocking read on the UI thread, but AFAIK that should work (though non-optimal).
-Steve
Programming blog: http://nitoprograms.blogspot.com/
Including my TCP/IP .NET Sockets FAQ
and How to Implement IDisposable and Finalizers: 3 Easy Rules
Microsoft Certified Professional Developer
How to get to Heaven according to the Bible
Todas las respuestas
-
miércoles, 21 de diciembre de 2011 7:48
Hi there,
You are hitting a known issue in the .NET developer preview version that Microsoft distributed at the BUILD conference.
The issue is caused by some subtle specifics of the WinRT UI thread. As a result, any blocking WinRT stream-IO from managed code will lead to a deadlock, if performed from the UI thread. Asynchronous IO (e.g. ReadAsync) will work fine. The development team is aware of the problem and is working to fix it.
Please note, however, that even if and when the issue is fixed, performing blocking IO on the UI thread is not a good idea. Your application will block and be unresponsive for the duration of the operation. Some .NET APIs do not have async equivalents (yet) and even once they do, converting code may require work. If you have to perform a blocking IO operation, make sure to offload it to the thread pool:
DoUIStuff(); Int32 x = await Task.Run(() => { OpenStream(); PerformBlockingIO(); ProcessResults(); return ComputeIOResults(); }); UseIOResults(x);This way you keep your application responsive at all times. As a side effect, you will also work around the abovementioned bug and avoid the deadlock.
Greg
(.NET Base Class Libraries Team)
- Propuesto como respuesta macrogreg miércoles, 21 de diciembre de 2011 7:49
- Marcado como respuesta Stephen ClearyMVP miércoles, 21 de diciembre de 2011 19:40
-
viernes, 08 de junio de 2012 15:32
Note this issue seems to be fixed in the Windows 8 Release Preview.
-
martes, 17 de julio de 2012 14:53
This type of WinRT IO-Stream still lead to deadlocks in the Windows 8 Release Preview.
string fileContent = await FileIO.ReadTextAsync(storageFile);
For example, the above code doesn't works for me and cause a deadlock.
However, answer given by macrogreg works fine, waiting a better answer.

