Windows Mobile 6.5 GPS Device - WaitForMultipleObjects returns 258 (timeout)

Posted by wizmagister on Stack Overflow See other posts from Stack Overflow or by wizmagister
Published on 2012-04-10T17:41:17Z Indexed on 2012/04/12 17:29 UTC
Read the original article Hit count: 198

I’ve created a GPS program that track positions in realtime in the background for Windows mobile 6.1 in 2008-2009. It ran fine on these devices for many years. For some reason, the same code never worked perfectly on Windows Mobile 6.5.

After many hour of operations (mostly when nobody use the device), I receive a “Timeout” (code 258) from the function "WaitForMultipleObjects":

this.GPSEvent_WaitValue = WaitForMultipleObjects(2, this.GPSEvent_Handles, 0, 45000);

Again, this can work for hours and suddenly, it's just impossible to get another position without : UPDATE: - Restarting the device (GoogleMap confirms that there's no GPS device present!)

It has something to do with Windows Mobile going to sleep and slowing up my thread.

Here's the core code (adapted from Microsoft SDK Sample):

/// <summary>
/// When "WindowsMobile" wake up the program to check for a new position
/// </summary>
private void OnNextGPSEvent_Callback()
{
  int SecondsToNextWakeUp = ETL.Mobile.Device.ScheduledCallback.MINIMUM_SECONDTONEXTWAKEUP;

  switch (this.SleepingState)
  {
    case SleepingStateType.SleepingForNextPosition:
      // Get position
      this.GPSEvent_WaitValue = (WaitForEventThreadResultType)WaitForMultipleObjects(2, this.GPSEvent_Handles, 0, 45000);

      switch (this.GPSEvent_WaitValue)
      {
        case WaitForEventThreadResultType.Event_LocationChanged:
          // Got a new position
          this.FireLocationChanged(this.GetCurrentPosition());

          // Manage device shutdown (save battery)
          if (this.PositionFrequency > MIN_SECONDS_FREQUENCY_FORDEVICE_SHUTDOWN)
          {
            // Close device
            this.CloseDevice();
            SecondsToNextWakeUp = (this.PositionFrequency - GPSDEVICE_LOAD_SECONDS_LOAD_TIME);
            this.SleepingState = SleepingStateType.SleepingBeforeDeviceWakeUp;
          }
          else
          {
            // Default Wait Time
            this.SleepingState = SleepingStateType.SleepingForNextPosition;
          }

          break;

        case WaitForEventThreadResultType.Event_StateChanged:
          break;

        case WaitForEventThreadResultType.Timeout:
        case WaitForEventThreadResultType.Failed:
        case WaitForEventThreadResultType.Stop:
          // >>>>>>>>>>>>>> This is where the error happens <<<<<<<<<<<<<<<<<<<<<<<<<<<
          // >>>>>>>>>>>>>> This is where the error happens <<<<<<<<<<<<<<<<<<<<<<<<<<<
          // >>>>>>>>>>>>>> This is where the error happens <<<<<<<<<<<<<<<<<<<<<<<<<<<

          // Too many errors
          this.ConsecutiveErrorReadingDevice++;
          if (this.ConsecutiveErrorReadingDevice > MAX_ERRORREADINGDEVICE)
          {
            this.CloseDevice();

            SecondsToNextWakeUp = (this.PositionFrequency - GPSDEVICE_LOAD_SECONDS_LOAD_TIME);
            this.SleepingState = SleepingStateType.SleepingBeforeDeviceWakeUp;
          }
          else
          {
            // Default Wait Time
            this.SleepingState = SleepingStateType.SleepingForNextPosition;
          }

          break;
      }
      #endregion
      break;

    case SleepingStateType.SleepingBeforeDeviceWakeUp:
      this.OpenDevice();

      SecondsToNextWakeUp = GPSDEVICE_LOAD_SECONDS_LOAD_TIME;
      this.SleepingState = SleepingStateType.SleepingForNextPosition;
      break;
  }

  if (this.IsListeningGPSEvent)
  {
    // Ajustement du prochain rappel
    this.NextGPSEvent_Callback.SecondToNextWakeUp = SecondsToNextWakeUp;
    this.NextGPSEvent_Callback.RequestWakeUpCallback();
  }
}
/// <summary>
///Create Thread
/// </summary>
private void StartListeningThreadForGPSEvent()
{
  // We only want to create the thread if we don't have one created already and we have opened the gps device
  if (this._GPSEventThread == null)
  {
    // Create and start thread to listen for GPS events
    this._GPSEventThread = new System.Threading.Thread(new System.Threading.ThreadStart(this.ListeningThreadForGPSEvent));
    this._GPSEventThread.Start();
  }
}
private void ListeningThreadForGPSEvent()
{
  this.GPSEvent_WaitValue = WaitForEventThreadResultType.Stop;
  this.IsListeningGPSEvent = true;

  // Allocate handles worth of memory to pass to WaitForMultipleObjects
  this.GPSEvent_Handles = Helpers.LocalAlloc(12);
  Marshal.WriteInt32(this.GPSEvent_Handles, 0, this._StopHandle.ToInt32());
  Marshal.WriteInt32(this.GPSEvent_Handles, 4, this._NewLocationHandle.ToInt32());
  Marshal.WriteInt32(this.GPSEvent_Handles, 8, this._GPSDeviceStateChanged.ToInt32());

  this.Start_NextGPSEvent_Timer(this.PositionFrequency);
  this.SleepingState = SleepingStateType.SleepingBeforeDeviceWakeUp;
  this.OnNextGPSEvent_Callback();
}

© Stack Overflow or respective owner

Related posts about windows-mobile

Related posts about gps