BeginXX/EndXXペア呼び出しでIOCPが使用されているとの記事があります。 しかし、私がそれらをテストすると、私の結果は、BeginExecuteReaderコールでIOCPが動作しないことを示しましたが、BeginGetResponseコールではうまくいきました。BeginExecuteReaderでIOCPが動作しない理由
私はこの結果と非常に混同しています。誰か私に理由を教えてもらえますか?私のテストコードに何か問題はありますか?ここで
は、以下のテストです:BeginGetResponseとテスト
コード:
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 コードと
テスト:
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
?
私は混乱しています...コールバックが別のスレッドで実行されることを期待しています。それは主に** Begin *を使った全体のポイント**です...?注:開始/終了コールバックを使用して待機ハンドルを開くだけでは無意味です。呼び出し元で待機する場合は、Begin *をまったく使用しないでください。 –
@MarcGravell、私は問題は、なぜワーカースレッドが2番目のケースで使用され、IOCPではないと思います。 – svick
I/O完了ポートは、単純なI/O要求で使用可能で、重複したRead/WriteFile()呼び出しによって開始されます。 SQL I/O要求については単純なことは何もなく、 "SQL Native Client"と呼ばれるソフトウェアの大規模な塊が存在します。 System.Data.SqlClientのC++/CLIコードのチャンクだけでなく、 TDSはプロトコルであり、SNIはインタフェースであり、チャネルはパイプ、ソケットまたは共有メモリと名付けることができる。すべてが、目立たないほど目立たない目に見え、目に見えない。 –