2008 年から 2009 年にかけて、 Windows モバイル 6.1のバックグラウンドで位置をリアルタイムで追跡する GPS プログラムを作成しました。これらのデバイスで何年も問題なく動作しました。何らかの理由で、同じコードがWindows Mobile 6.5で完全に機能することはありませんでした。
何時間もの操作の後 (ほとんどの場合、誰もデバイスを使用していない場合)、関数「WaitForMultipleObjects」から「タイムアウト」(コード 258) を受け取ります。
this.GPSEvent_WaitValue = WaitForMultipleObjects(2, this.GPSEvent_Handles, 0, 45000);
繰り返しますが、これは何時間も機能する可能性があり、突然、別の位置を取得することは不可能です: 更新: - デバイスを再起動します (GoogleMap は GPS デバイスが存在しないことを確認します!)
これは、Windows Mobile がスリープ状態になり、スレッドが遅くなることと関係があります。
コア コードは次のとおりです (Microsoft SDK サンプルから適応)。
/// <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();
}