2013-07-23 5 views
5

私はC#ソケット(コールバックにIOCPを使用しています)を使用しています。処理ロジックが遅れている天気を判断する方法が必要です。コールバックによって処理されていない完了した操作のサイズを私に与えることができるAPI呼び出しがありますか?未処理の完了した操作がAPI呼び出しによってIOCPにキューされている回数を知ることはできますか?

ハートビート操作のようなものを使用して、キューにポストし、コールバックの経過時間が遅れているかどうかを判断しましたが、可能であれば、より直接的なルートを選択します(Plus I don ' .Net内部コントロールのIOCPハンドルに簡単にアクセスできます)。

答えて

4
文書化されたAPIを経由して

ないが、あなたはこれを試みることができる...かなりきちんとしたのですが、.NETはその内部で作成された `m_hIOCP`を公開していません

/* 
GetIocpQueueCount 

Description: 
Returns the number of queued IOCP work and I/O completion items. 

Remarks: 
Microsoft declined to implement the NtQueryIoCompletion routine 
for user mode. This function gets past that omission by calling 
the NTDLL.DLL function dynamically. 

Returns: 
Number of items in the queue at the instant this function was 
called, or -1 if an error occurred. Errors can be retrieved 
by calling GetLastError. 
*/ 
long GetIocpQueueCount() 
{ 
    long lQueueDepth = -1; 

    typedef DWORD (WINAPI *LPFNNTQUERYIOCOMPLETION)(HANDLE, int, PVOID, ULONG, PULONG); 

    static LPFNNTQUERYIOCOMPLETION pfnNtQueryIoCompletion = NULL; 

    if (MFTASKQUEUENOTCREATED != m_dwStatus) 
    { 
     DWORD rc = NO_ERROR; 

     /* need to load dynamically */ 

     if (NULL == pfnNtQueryIoCompletion) 
     { 
     /* Now dynamically obtain the undocumented NtQueryIoCompletion 
      * entry point from NTDLL.DLL 
      */ 

     HMODULE hmodDll = ::GetModuleHandleW(L"ntdll.dll"); 

     // NTDLL is always loaded, just get its handle 

     if (NULL != hmodDll) 
     { 
      pfnNtQueryIoCompletion = (LPFNNTQUERYIOCOMPLETION)::GetProcAddress(
       hmodDll, 
       "NtQueryIoCompletion"); // NB: ANSI 
     } 
     } 

     if (NULL != pfnNtQueryIoCompletion) 
     { 
     rc = (pfnNtQueryIoCompletion)(
      m_hIOCP, 
      0, 
      (PVOID)&lQueueDepth, 
      sizeof(lQueueDepth), 
      NULL); 
     } 
     else 
     { 
     rc = ERROR_NOT_FOUND; 
     } 
     ::SetLastError(rc); 
    } 
    return lQueueDepth; 
} 
+0

。 – dtb

+0

これは素晴らしいです! @ dtb問題はない、私は反射でそれを抽出することができます。しかし、心配することは、心配することは、私がどれほど遠いかをより現実的に見ることができると思います。しかし、ハートビートを実装するのは、この単純な方法よりも面倒です.net IOCPスレッドプールにカスタムハンドラを実装する方法がないためです。私はハートビートを実装するためにサーバーにソケット接続を使用する必要があります。 –

+0

反射でハンドルを取り出すことができる場合は、コードをどこかに投稿してください。私は年を重ねてそれを試みてきました。 – dtb

関連する問題