【发布时间】:2012-02-03 12:34:46
【问题描述】:
The Good Book 说,在实现异步编程模型时,总是有可能连续多次同步调用回调,导致堆栈溢出。问题是我什至无法重现这种情况。即使是下面的程序,它通过 tcp 向自己发送一条大消息,然后一次读取一个字节,在几十次运行中一次陷入只有几级深度的递归。
那么,这真的是个问题吗?或者它只是吓唬人,让你在已经很庞大的模式中添加两个额外的方法?如果真的是,为什么不直接将 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);
}
}
}
【问题讨论】:
标签: c# asynchronous threadpool stack-overflow