我试图在完成写作后处理NetworkStream
。我已尝试将流包装在using()
中,如此:
using (NetworkStream stream = client.GetStream())
{
foreach (byte[] command in fadeSceneOut)
{
if (stream.CanWrite)
{
stream.BeginWrite(command, 0, command.Length, new AsyncCallback(SendCallback), stream);
}
}
}
但是我收到一个System.ObjectDisposedException
声明该对象已经被处理掉了,并且在我发送EndWrite()
的回调中无法访问该对象:
private static void SendCallback(IAsyncResult ar)
{
try
{
NetworkStream stream = (NetworkStream)ar.AsyncState;
stream.EndWrite(ar);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
我的理解是,在将所有命令写入流之后执行离开using
块之前,不会处理流。显然我在这里弄错了,有人可以就正确的方法提出建议吗?
修改:包含await
方法:
static void Main(string[] args)
{
Task.WaitAll(Run());
}
public static async Task Run()
{
// Get a scene
var scene = GrabSceneFromUser();
// Get scene commands
var fadeSceneIn = LightSwarmHelper.BuildSceneCommands(scene);
var fadeSceneOut = LightSwarmHelper.BuildSceneCommands(scene, false);
// Send commands to device
using (TcpClient client = new TcpClient(ConfigurationManager.AppSettings["Host"], Convert.ToInt32(ConfigurationManager.AppSettings["Port"])))
{
using (NetworkStream stream = client.GetStream())
{
foreach (byte[] command in fadeSceneOut)
{
if (stream.CanWrite)
{
await stream.WriteAsync(command, 0, command.Length); //stream.BeginWrite(command, 0, command.Length, new AsyncCallback(SendCallback), stream);
}
}
}
}
}
答案 0 :(得分:3)
由于对stream.BeginWrite(...)的调用是非阻塞的,因此在写操作完成之前将使用using块,因此异常。处理流的适当位置将在回调函数中。
答案 1 :(得分:1)
Stefans的回答是正确的,并指出了根本原因。你应该接受它。我将添加另一种解决问题的方法:
此代码已过时,请使用等待。接下来,您将创建无限量的并发发送。这很容易耗尽资源。它甚至可能导致腐败,不确定。
按顺序执行发送。这是非常容易和自然的等待。
if (stream.CanWrite)
这没有想到... CanWrite将始终返回true,如果返回false,您将无所事事并隐藏错误。