2012-03-31 11 views
1

BeginXX/EndXXペア呼び出しでIOCPが使用されているとの記事があります。 しかし、私がそれらをテストすると、私の結果は、BeginExecuteReaderコールでIOCPが動作しないことを示しましたが、BeginGetResponseコールではうまくいきました。BeginExecuteReaderでIOCPが動作しない理由

私はこの結果と非常に混同しています。誰か私に理由を教えてもらえますか?私のテストコードに何か問題はありますか?ここで

は、以下のテストです:BeginGetResponseと

  1. テスト

    コード:

    public static void IoThread2() 
    { 
        ThreadPool.SetMinThreads(5, 3); 
        ThreadPool.SetMaxThreads(5, 3); 
        int w; int io; 
        ThreadPool.GetAvailableThreads(out w, out io); 
        int cid = Thread.CurrentThread.ManagedThreadId; 
        Console.WriteLine("Begin:" + w.ToString() + ";" + io.ToString() + "; id = " + cid.ToString()); 
        ManualResetEvent waitHandle = new ManualResetEvent(false); 
        WebRequest request = HttpWebRequest.Create("http://www.cnblogs.com/"); 
        AsyncCallback cb = new AsyncCallback(IOThread2CallBack); 
        request.BeginGetResponse(cb, request); 
        waitHandle.WaitOne(); 
    } 
    
    public static void IOThread2CallBack(IAsyncResult ar) 
    { 
    try 
    { 
        WebRequest request = (WebRequest)ar.AsyncState; 
        int w2; int io2; 
        ThreadPool.GetAvailableThreads(out w2, out io2); 
        int cid2 = Thread.CurrentThread.ManagedThreadId; 
        Console.WriteLine("End:" + w2.ToString() + ";" + io2.ToString() + "; id = " + cid2.ToString()); 
        var response = request.EndGetResponse(ar); 
        }catch (Exception ex){ } 
    } 
    

    結果:

    Begin:5;3; id = 10 
    End:5;2; id = 13 
    

    一つのIOスレッドがコールバックを実行するために使用されました。 BeginExecuteReader コードと

  2. テスト:

    public static void IoThread1() 
    { 
        ThreadPool.SetMinThreads(5, 3); 
        ThreadPool.SetMaxThreads(5, 3); 
        int w; int io; 
        ThreadPool.GetAvailableThreads(out w, out io); 
        int cid = Thread.CurrentThread.ManagedThreadId; 
        Console.WriteLine("Begin:" + w.ToString() + ";" + io.ToString() + "; id = " + 
            cid.ToString()); 
        SqlConnection connection = new SqlConnection(connectionString); 
        connection.Open(); 
        AsyncCallback da = new AsyncCallback(IoThreadCallBack); 
        SqlCommand command = new SqlCommand(s_QueryDatabaseListScript, connection); 
        IAsyncResult ir = command.BeginExecuteReader(da,        
              command,System.Data.CommandBehavior.CloseConnection); 
        ManualResetEvent waitHandle = new ManualResetEvent(false); 
        waitHandle.WaitOne(); 
    } 
    
    public static void IoThreadCallBack(IAsyncResult ar) 
    { 
    int w; int io; 
    ThreadPool.GetAvailableThreads(out w, out io); 
    int cid = Thread.CurrentThread.ManagedThreadId; 
    Console.WriteLine("End:" + w.ToString() + ";" + io.ToString() + "; id = " + 
            cid.ToString()); 
    SqlCommand command = (SqlCommand)ar.AsyncState; 
    StringBuilder sb = new StringBuilder(); 
    try 
    { 
         using (SqlDataReader reader = command.EndExecuteReader(ar)) 
         { 
          while (reader.Read()) 
          { 
           sb.Append(reader.GetString(0)).Append("; "); 
          } 
         } 
        } 
        catch (Exception ex){ } 
        finally 
        { 
         command.Connection.Close(); 
        } 
    } 
    

    結果:別の作業スレッドがコールバック

問題は何を実行するのに使用された

Begin:5;3; id = 10 
End:4;3; id = 7 

+1

私は混乱しています...コールバックが別のスレッドで実行されることを期待しています。それは主に** Begin *を使った全体のポイント**です...?注:開始/終了コールバックを使用して待機ハンドルを開くだけでは無意味です。呼び出し元で待機する場合は、Begin *をまったく使用しないでください。 –

+0

@MarcGravell、私は問題は、なぜワーカースレッドが2番目のケースで使用され、IOCPではないと思います。 – svick

+2

I/O完了ポートは、単純なI/O要求で使用可能で、重複したRead/WriteFile()呼び出しによって開始されます。 SQL I/O要求については単純なことは何もなく、 "SQL Native Client"と呼ばれるソフトウェアの大規模な塊が存在します。 System.Data.SqlClientのC++/CLIコードのチャンクだけでなく、 TDSはプロトコルであり、SNIはインタフェースであり、チャネルはパイプ、ソケットまたは共有メモリと名付けることができる。すべてが、目立たないほど目立たない目に見え、目に見えない。 –

答えて

0

あなたのレトロはとても創造的です。これは興味深いケースです。

コマンドテキスト「WAITFOR DELAY '02:00 ';」を使用して100個のSqlCommandsを起動してみてください。スレッドのカウントが時間とともにどのように発展するかを観察します(統計を出力するタイマーを開始します)。

私の推測では、100スレッド以下が消費されていることがわかります(非同期動作のこの部分が機能していることを意味します)。何らかの理由でSqlCommandがスレッドプールのスレッドを間違って使用していますが、スケーラビリティが低下することはありません。

+0

私たちが観察したことは、コールバックがワーカースレッド上で実行されたことを意味します。しかし、IOはまだIOCPとして実行されている可能性があります。何千ものスレッドを持たずに何千もの優れた操作を行うことができるので、重要なことです。この実験を試してください。 – usr

関連する問題