Search code examples
c#socketscompact-frameworkbackgroundworker

Problems on Compact Framework when communication is lost


I have a problem on a hand held device that should be listening for messages from my server application. When the device loses connection to the network my server is on, this background worker (implemented from OpenNetCF) stops responding. I've placed messages in the ProgressChanged and RunWorkerCompleted events to see when they are raised, and in the following code after the RecieveFrom in the while loop, and after the loop termination, as well as in all of the exceptions. I don't see the messages from the exceptions, or after the while loop at all, and the messages stop after the connection is lost. All of the messages are shown by setting the text in a visible label, with the background colour of the label changing so that I can see if the loop is running. The loop seems to stop running, even after the connection is re-gained, and attempting to re-run the backgroundworker generates an "Already in use" exception. So, why would the worker stop responding while continuing to run?

  private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
  {
      BackgroundWorker wWorker = (BackgroundWorker)sender;
      byte[] wBytes = new Byte[4096];
      string wsReceive;
      EndPoint wRemoteEP = (EndPoint)new IPEndPoint(IPAddress.Any, 0);

      try
      {
          while (true)
          {
              if (wWorker.CancellationPending)
              {
                  break;
              }

              mSocket.ReceiveFrom(wBytes, ref wRemoteEP);
              if (wBytes.Length < 1)
              {
                  continue;
              }
              wsReceive = Encoding.ASCII.GetString(wBytes, 0, wBytes.Length);

              wWorker.ReportProgress(0, wsReceive);
          }
          mSocket.Close();
      }
      catch (ThreadAbortException)
      {
      }
      catch (ThreadStateException)
      {
      }
      catch (Exception E)
      {
          MessageBox.Show(E.Message, "Communication Error");
      }
  }

Solution

  • Right from the docs on Socket.ReceiveFrom:

    If no data is available for reading, the ReceiveFrom method will block until data is available

    So when communication is lost, you're unable to receive and your ReceiveFrom call blocks indefinitely. It's going to stop reporting anything while it waits for data, but the thread is still alive and therefore the BackgroundWorker can't be re-run.