「Good Book」によれば、非同期プログラミングモデルを実装すると、スタックオーバーフローを引き起こす行内で何度も同期して呼び出される可能性が常にあります。問題は、私はこの状況を再現することに近づくことさえできないということです。下記のプログラムでも、tcpで大量のメッセージを送信し、一度に1バイトずつ読み込みます.1回の数十回の実行で再帰が数レベルにしかなりません。APMでスタックオーバーフローを防ぐため
これは本当に問題ですか?それとも、それは単に大規模なパターンに2つの余分なメソッドを追加するだけで怖いですか?実際には、BeginMethodをコールバックが同じスレッドで実行されたときに直接呼び出すのではなく、スレッドプールのキューに入れるのはなぜですか?
using System;
using System.Linq;
using System.Net.Sockets;
using System.Net;
class Program {
static byte[] buff = new byte[1];
static int cntr = 0;
static void Main(string[] args) {
var listener = new TcpListener(IPAddress.Loopback, 11111);
listener.Start();
new Action(() => {
byte[] message = Enumerable.Range(0, 100000).Select(i => (byte)i).ToArray();
var client = new TcpClient();
client.Connect(IPAddress.Loopback, 11111);
using (var s = client.GetStream()) s.Write(message, 0, message.Length);
}).BeginInvoke(null, null);
var stream = listener.AcceptTcpClient().GetStream();
stream.BeginRead(buff, 0, buff.Length, callback, stream);
Console.ReadLine();
}
static void callback(IAsyncResult iar) {
if (iar.CompletedSynchronously) Console.Write(cntr++ +" "); else cntr=0;
var stream = iar.AsyncState as NetworkStream;
if (stream.EndRead(iar) > 0) {
stream.BeginRead(buff, 0, buff.Length, callback, stream);
}
}
}
非同期呼び出しは、そのジョブを同期して完了させることができ、スレッドプールをまったく使用しませんが、タスクが非常に迅速に終了できる場合にのみ使用できます。ソケットから1バイトを読み取ることは、私が思い付くことができる最も小さい実生活の仕事です。 – user1096188