title: ConnectAsync() never finishes in C# Visual Studio
body: <p><strong>TLDR:</strong> Creating a UWP app for Raspberry Pi 3 Model B running Windows 10 IoT and <code>StreamSockets.ConnectAsync()</code> (RFCOMM) sometimes finishes and sometimes it takes an extraordinarily long time to fail ("No more data is available. (Exception from HRESULT: 0x80070103)") or just never finishes. Why is that? The debugger in Visual Studio has been used without success.</p>
  
  <p>I am currently creating a UWP app using Visual Studio 2017 and writing in C#. The app is being tested on my Raspberry Pi 3 Model B running Windows 10 IoT, and the purpose of the app is to connect to Arduino's that have the HC-06 Bluetooth module using RFCOMM.</p>
  
  <p>I have a button for testing the connection between the Raspberry Pi and the Arduino, which will try connecting (in turn) to all the Bluetooth devices I have defined.</p>
  
  <p>I have, however, encountered a 'bug'; sometimes when I click the button, the connection test works fine, a connection is established and I can also see the data sent printed in the Serial Monitor on my Arduino.
  The problem is that sometimes the call to <code>StreamSockets.ConnectAsync()</code> just never finishes or uses an extraordinarily long time to fail with the exception "No more data is available. (Exception from HRESULT: 0x80070103)".</p>
  
  <p>My question is what could be causing such a behavior?</p>
  
  <p>All of the code below is located in <code>Settings.xaml.cs</code>.</p>
  
  <pre><code>public sealed partial class Settings : Page
  {
      private MainPage rootPage = Current;
  
      private StreamSocket socket = null;
      private DataWriter writer = null;
      private RfcommDeviceService service = null;
      private BluetoothDevice bluetoothDevice;
  
      public Settings()
      {
          InitializeComponent();
      }
  
      protected override void OnNavigatedTo(NavigationEventArgs e)
      {
          rootPage = Current;
      }
  
      protected override void OnNavigatedFrom(NavigationEventArgs e)
      {
          Disconnect();
      }
  
      void App_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
      {
          Disconnect("App suspension discconects");
      }
  
  // Rest of the code is below here //
  
  }
  </code></pre>
  
  <h3>Flow of my program:</h3>
  
  <p>When the button is clicked, <code>ConnectionTestButton_Click</code> is called:</p>
  
  <pre><code>private void ConnectionTestButton_Click(object sender, RoutedEventArgs e)
  {
      ConnectionTest();
  }
  </code></pre>
  
  <p>Which in turn calls <code>ConnectionTest()</code>:</p>
  
  <pre><code>private async void ConnectionTest()
  {
      rootPage.NotifyUser("Connection test in progress...", NotifyType.StatusMessage);
      Disconnect(); // Ensures that there is no residue data from previous attempts
  
    // This connects to the Bluetooth devices I have specified in MainPage.xaml.cs in turn
    // There is no problem with the declaration of the devices as this works correctly
      foreach (KeyValuePair&lt;string, string&gt; device in Constants.BtDevices)
      {
          await Task.Run(() =&gt; ConnectToBtDevice(device.Value, true));
          await Task.Delay(5000);
          Disconnect("Connection test");
          await Task.Delay(5000);
      }
  }
  </code></pre>
  
  <p>Which calls <code>ConnectToBtDevice()</code> <em>x</em> times, where <em>x</em> is defined by how many Bluetooth devices I have declared in <code>MainPage.xaml.cs</code>:</p>
  
  <pre><code>private async Task ConnectToBtDevice(string btId, bool connectionTest = false)
  {
      try
      {
          bluetoothDevice = await BluetoothDevice.FromIdAsync(btId);
          rootPage.NotifyUser(
                   Constants.BtDevices.FirstOrDefault(x =&gt; x.Value == btId).Key
                   + " found, trying to connect...",
                   NotifyType.StatusMessage);
      }
      catch (Exception ex)
      {
          rootPage.NotifyUser(
                   "An exception was thrown when trying to receive the Bluetooth device "
                   + ex.Message,
                   NotifyType.ErrorMessage);
          return;
      }
  
      if (bluetoothDevice == null)
      {
          rootPage.NotifyUser("Bluetooth device returned null",
                   NotifyType.ErrorMessage);
      }
  
      var rfcommServices = await bluetoothDevice.GetRfcommServicesAsync();
      if (rfcommServices.Services.Count &gt; 0)
      {
          service = rfcommServices.Services[0];
      }
      else
      {
          rootPage.NotifyUser("No RFCOMM services found on the device",
                   NotifyType.ErrorMessage);
          return;
      }
  
      lock (this)
      {
          socket = new StreamSocket();
      }
      try
      {
        // This call is what is causing my headache
          await socket.ConnectAsync(service.ConnectionHostName,
                       service.ConnectionServiceName,
                       SocketProtectionLevel
                        .BluetoothEncryptionAllowNullAuthentication);
  
          rootPage.NotifyUser("Hostname: "
                   + service.ConnectionHostName
                   + " Servicename: "
                   + service.ConnectionServiceName,
                   NotifyType.StatusMessage);
  
      // Ensure utf8 is used for the reader and writer
      // Not sure if this is actually necessary?
          writer = new DataWriter(socket.OutputStream)
          {
              UnicodeEncoding = UnicodeEncoding.Utf8
          };
          DataReader reader = new DataReader(socket.InputStream)
          {
              UnicodeEncoding = UnicodeEncoding.Utf8
          };
  
          rootPage.NotifyUser("Connected to "
                   + Constants.BtDevices.FirstOrDefault(x =&gt; x.Value == btId).Key,
                   NotifyType.SuccessMessage);
  
          ReceiveData(reader, connectionTest);
  
       // Send some data if the connection is for test purposes only
          if (connectionTest)
          {
              await SendData("Test");
          }
      }
      catch (Exception ex)
      {
          rootPage.NotifyUser("An exception was thrown when trying to connect to "
                   + Constants.BtDevices.FirstOrDefault(x =&gt; x.Value == btId).Key
                   + " "
                   + ex.Message,
                   NotifyType.ErrorMessage);
          Disconnect();
      }
  }
  </code></pre>
  
  <p>It also calls <code>Disconnect</code> if a connection has been established and data has been sent:</p>
  
  <pre><code>private void Disconnect(string disconnectReason = null)
  {
      if (writer != null)
      {
          writer.DetachStream();
          writer = null;
      }
  
      if (service != null)
      {
          service.Dispose();
          service = null;
      }
      lock (this)
      {
          if (socket != null)
          {
              socket.Dispose();
              socket = null;
          }
      }
      if (disconnectReason != null)
      {
          rootPage.NotifyUser("Disconnected. Reason: "
                   + disconnectReason,
                   NotifyType.CautionMessage);
      }
  }
  </code></pre>
  
  <p>(If any of the code is weirdly indented/formatted it is probably because I tried to limit the line length for this question, so I quickly formatted it in the question text editor)</p>
  
  <p>I have tried the debugger in Visual Studio but without success in locating what is wrong, as everything seems normal. And by normal I mean that every variable is what it is supposed to be, e.g. <code>service.ConnectionHostName</code> and <code>service.ConnectionServiceName</code> are both set to the correct values.
  <code>{(XX:XX:XX:XX:XX:XX)}</code> and <code>"Bluetooth#BluetoothbX:XX:XX:XX:XX:XX-XX:XX:XX:XX:XX:XX#RFCOMM:XXXXXXXX:{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"</code> respectively ( "X'ed" for privacy ( not that it really matters that much, but better safe than sorry ;) ))</p>
  
  <p>Neither <code>SendData()</code> nor <code>ReceiveData()</code> is really relevant for this question, as the problem lies before any of those methods are called, but I will happily include them if requested.</p>
  
  <p>I can also add that I have used the <a href="https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/BluetoothRfcommChat" rel="nofollow noreferrer">BluetoothRfcommChat</a> sample as a reference because I am very new to UWP development, networking/Bluetooth and C# in general.</p>
  
  <p>( Also, let me know if there is anything wrong with the formatting of the question itself )</p>
  
  <h3>Update:</h3>
  
  <p>Sometimes when the connection takes too long to establish, I can encounter the exception: "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond."</p>
  
  <h3>Update 2:</h3>
  
  <p>I added a <code>CancellationToken</code> to have a timeout function of the <code>ConnectAsync</code> method, however, <code>ConnectAsync</code> only sometimes registers cancellation requests, which means that sometimes it is still stuck.</p>
  
  <p>The way I have it implemented:</p>
  
  <pre><code>// Called in constructor
  private CancellationTokenSource connectionCts = null;
  
  // Called in 'ConnectoToBtDevice' (same place as original)
  try
  {
    // public const int ConnectionTimeout = 5000;
      connectionCts = new CancellationTokenSource();
      connectionCts.CancelAfter(Constants.ConnectionTimeout);
      await socket.ConnectAsync(service.ConnectionHostName,
                   service.ConnectionServiceName)
                    .AsTask(connectionCts.Token);
  
    ...
  
  }
  catch (TaskCanceledException tEx)
  {
      rootPage.NotifyUser("Connection timed out.", NotifyType.ErrorMessage);
      Disconnect();
  }
  
  // Called in 'Disconnect'
  if (connectionCts != null)
  {
      connectionCts.Dispose();
      connectionCts = null;
  }
  </code></pre>
  
  <h3>Update 3:</h3>
  
  <p>It appears that if I try using:</p>
  
  <pre><code>await bluetoothDevice.GetRfcommAsync(BluetoothCacheMode.Uncached);
  </code></pre>
  
  <p>(Using the <code>BluetoothCacheMode.Uncached</code>) It gets stuck at that line instead. I have no idea if this has a connection with the above problem, but it might.</p>
  
  <h3>Update 4:</h3>
  
  <p>Okay, so I have now tested a bit and found out that it has no problem connecting to my phone. This makes it look like there is a problem connecting using the serial port service that is on my HC-06 modules (UUID = "{00001101-0000-1000-8000-00805F9B34FB}'"). The problem is that this is the only RFCOMM service my HC-06 provides.</p>