locked
StreamSocket.ConnectAsync() never completes in C# apps (Was: WinRT component behaves differently in C# and WinJS apps)

    Question

  • Hi,

    I've written a WinRT component in C# that uses StreamSocket extensively, i.e. there lots of awaits on async socket operations.

    When that component is used by a WinJS app, it works perfectly. However, when it is used by a C# app, it behaves oddly. For instance, 'await socket.ConnectAsync()' bails out of the method without any exception.

    My suspicion is that WinJS and C# set up different threading models app-wide. And I'd like to understand that better. In particular, can someone explain the threading aspects of the two possible interop hops in this case - the hop from the app to the component, and the hop from the component to the platform. Is the second hop identical in both contexts?

    Thanks,
    Zlatko



    This posting is provided "AS IS" with no warranties, and confers no rights.


    • Edited by Zlatko Michailov - MSFT Tuesday, March 18, 2014 7:44 PM Changing the title to reflect the deeper problem.
    Friday, March 14, 2014 6:59 PM

Answers

  • Yes, I solved the problem. I should have updated the thread. Sorry about that. Thanks for reminding me.

    The problem is not specific to StreamSocket. It is general to Windows RT. Briefly, you should never do anything like Task.Wait() or Task.Result on the main thread.

    The moment that happens, Windows RT wipes out the apartment or whatever the container name is these days. You don't see an exception. Even the app itself doesn't seem to realize what has happened.

    I had ended up in that situation because I had pasted the code from a Visual Studio Test project where all test methods must be synchronous. (I still can't wrap my head around how 'Visual Studio Test Project for Windows Store Apps' can possibly exist when Windows Store doesn't allow you to block but the Visual Studio Test Project requires you to block. That sounds like an oxymoron.)

    So look at your UI event handlers, and make sure you don't wait on tasks.

    Zlatko


    This posting is provided "AS IS" with no warranties, and confers no rights.

    Friday, April 11, 2014 9:08 PM

All replies

  • Here's a simple repro: Create a button 'button1' on MainPage.xaml and paste this code in MainPage.xaml.cs:

    For the record, the app has 'Internet (Client)' and 'Private Networks (Client & Server)' capabilities, and SQL Server is listening on port 1433 on the same box.

    private void button1_Click(object sender, RoutedEventArgs e) { var x = Test1().Result; } private async Task<bool> Test1() { var _clientSocket = new StreamSocket();

    // It hangs with or without this section //_clientSocket.Control.OutboundBufferSizeInBytes = 0x200; //var _clientReader = new DataReader(_clientSocket.InputStream); //_clientReader.InputStreamOptions = InputStreamOptions.Partial; //var _clientWriter = new DataWriter(_clientSocket.OutputStream);

    await _clientSocket.ConnectAsync(new HostName("localhost"), "1433", SocketProtectionLevel.PlainSocket); return true; }


    This posting is provided "AS IS" with no warranties, and confers no rights.

    Saturday, March 15, 2014 5:26 AM
  • My 1 Cent :)

    Please refer Best Practices in Asynchronous Programming I have seen people using async void and that causes issues when exceptions are thrown.

    Specifically for your issue, it will be relay hard to guess unless and until we get to see your full code. 

    Regarding thread model difference between C# and WinJS I am not sure,  I think someone from Dev team can explain that or point to right place.


    -- Vishal Kaushik --

    Please 'Mark as Answer' if my post answers your question and 'Vote as Helpful' if it helps you. Happy Coding!!!

    Saturday, March 15, 2014 7:35 PM
  • Here are a couple more clues:

    • The behavior is exactly the same when I remove the capabilities from the app manifest.
    • An equivalent WinJS app works fine.

    I suspect the C# implementation of StreamSocket.ConnectAsync() misses the capabilities somehow, though I have no explanation how that could happen only in C#...

    @Vishal - I don't see the relevance of your suggestion - I don't have any 'async void' method in my projects...


    This posting is provided "AS IS" with no warranties, and confers no rights.

    Sunday, March 16, 2014 5:55 AM
  • Ping...

    This posting is provided "AS IS" with no warranties, and confers no rights.

    Tuesday, March 18, 2014 7:46 PM
  • Did you find a solution?

    I have the same problem. (VS2013 update 2 RC)

    Friday, April 11, 2014 8:34 PM
  • Yes, I solved the problem. I should have updated the thread. Sorry about that. Thanks for reminding me.

    The problem is not specific to StreamSocket. It is general to Windows RT. Briefly, you should never do anything like Task.Wait() or Task.Result on the main thread.

    The moment that happens, Windows RT wipes out the apartment or whatever the container name is these days. You don't see an exception. Even the app itself doesn't seem to realize what has happened.

    I had ended up in that situation because I had pasted the code from a Visual Studio Test project where all test methods must be synchronous. (I still can't wrap my head around how 'Visual Studio Test Project for Windows Store Apps' can possibly exist when Windows Store doesn't allow you to block but the Visual Studio Test Project requires you to block. That sounds like an oxymoron.)

    So look at your UI event handlers, and make sure you don't wait on tasks.

    Zlatko


    This posting is provided "AS IS" with no warranties, and confers no rights.

    Friday, April 11, 2014 9:08 PM
  • You are correct. I did a .Result

    I changed it to await and it worked.


    Saturday, April 12, 2014 10:16 AM