2011-07-27 33 views
0

GetLastErrorは、ReadFileの後に1453ERROR_WORKING_SET_QUOTAを返します。メモリリークや何かがあることを意味しますか?このコードは、USBデバイスと通信するために使用されます。この手順は、テストの10時間(40ミリ秒ごとに読んで)動作し、その後エラーが発生します。ReadFileの戻り値がERROR_WORKING_SET_QUOTA

uint ReadBytesCount = 0; 
byte[] bytes = new byte[0x8000]; 
fixed (byte* p = bytes) 
{ 
    if (UnsafeMethods.ReadFile(handle, p, 0x8000, out ReadBytesCount, intOverlapped) == 0) 
    { 
     int hr = UnsafeMethods.GetLastError(handle); 
     if (hr == UnsafeMethods.ERROR_ACCESS_DENIED) 
     { 
      doCleanup = true; 
      break; 
     } 
     if (hr == NativeMethods.ERROR_IO_PENDING) 
     { 
      int error = 0; 

      // if we get IO pending, MSDN says we should wait 
      // on the WaitHandle, then call GetOverlappedResult 
      // use timeout to ensure that first time read 
      bool success = waitReadEventWaitHandle.WaitOne(1000); 
      if (success) 
      { 
       uint ReadInProgressCount = 0; 
       success = UnsafeMethods.GetOverlappedResult(
          handle, 
          intOverlapped, 
          ref ReadInProgressCount, 
          false); 
       if (!success) 
        error = UnsafeMethods.GetLastError(handle); 
       ReadBytesCount += ReadInProgressCount; 

       if (!success && error != 0) 
       { 
        // Ignore ERROR_IO_INCOMPLETE, because there's a chance 
        // one of those while shutting down 
        if (!(
         (error == UnsafeMethods.ERROR_IO_INCOMPLETE) 
         && ShutdownLoop) 
         ) 
         Debug.Assert(false, 
         "GetOverlappedResult,might leak intOverlapped memory" 
         + error.ToString()); 
       } 
      } 
     } 
     else if (hr != UnsafeMethods.ERROR_INVALID_PARAMETER) 
     { 
      // ignore ERROR_INVALID_PARAMETER errors. 
      Debug.Assert(false, "ReadUsbLoop returned error " + hr); 
     } 
    } 
} 
+0

'File.ReadAllText'メソッドを使用していない理由は何ですか?なぜ安全でないコードですか? –

+0

UnsafeMethodsは、カスタムUSBドライバFTD2XX.DLLにapiをラップします。パフォーマンス要件のために重複した読み込み/書き込みを使用しています – baraban

+0

デバッグ用に 'File.ReadAllText'を使用するようにコードを変更すると、どのようなエラーが発生しますか? –

答えて

0

私が発見した唯一の意味のある情報は、MySQLのバグリストunconditional exit(1) on ERROR_WORKING_SET_QUOTA 1453 (0x5AD) for InnoDB backendにありました。

エラーが100msの間、SQL Serverワーカー利回りを発生し、再び読み取り 操作をしようとします。このループは、I/Oが正常に発行されるまで続きます。 この動作を簡単な例で示します。私は100ミリ秒のための睡眠のスレッドを試してみて、読んで再試行する必要があるという結論に私を導く

WHILE(  FALSE == ReadFile() 
    && (1450 == GetLastError() || 1453 == GetLastError()) 
) 
{ 
    Yield(100); 
} 

uint ReadBytesCount = 0; 
byte[] bytes = new byte[0x8000]; 
fixed (byte* p = bytes) 
{ 
    if (UnsafeMethods.ReadFile(handle, p, 0x8000, out ReadBytesCount, intOverlapped) == 0) 
    { 
     int hr = UnsafeMethods.GetLastError(handle); 
     if (hr == UnsafeMethods.ERROR_ACCESS_DENIED) 
     { 
      doCleanup = true; 
      break; 
     } 
     if (hr == NativeMethods.ERROR_IO_PENDING) 
     { 
      // do something 
     } 
     else if (hr == UnsafeMethods.ERROR_WORKING_SET_QUOTA || 
       hr == UnsafeMethods.ERROR_NO_SYSTEM_RESOURCES) 
     { 
      Thread.Sleep(100); 
     } 
     else if (hr != UnsafeMethods.ERROR_INVALID_PARAMETER) 
     { 
      // ignore ERROR_INVALID_PARAMETER errors. 
      Debug.Assert(false, "ReadUsbLoop returned error " + hr); 
     } 
    } 
} 

更新:いいえ、それは助けにはなりませんでした。今、タイムアウトエラーを投げ捨て、デバイスを再び開くことを検討しています。