调度程序派遣的代表永远不会被解雇
本文关键字:永远 调度程序 | 更新日期: 2023-09-27 18:23:39
我正在尝试触发一个方法,作为网络流上的异步读取操作的结果。读取操作通过 BeginRead 和 EndRead 完成,导致在使用 BeginRead 指定的回调中调用 EndRead。都是非常基本的东西。现在,由于回调是在系统生成的线程中完成的,因此从NetworkStream读取的数据不再归我的线程所有,称为BeginRead。为了克服这个问题,我编写了一个方法来进一步处理读取的数据,我尝试通过线程的调度程序调用它。
// These are created in my Thread
private delegate void ReceiverCallback(IPEndPoint sender, byte[] data);
private Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
回调如下所示:
private void DataReceived(IAsyncResult result)
{
DataReceivedStruct drs = (DataReceivedStruct)result.AsyncState;
NetworkStream used = drs.stream;
AutoResetEvent handle = drs.waitHandle;
used.EndRead(result);
DispatchRaiseReceived(readBuffer);
handle.Set();
}
DataReceivedStruct 是一个简单的结构,用于保存 NetworkStream 和 AutoResetEvent。ReadBuffer 是一个长度为 1024 的全局私有字节[],因为 BeginRead 和 EndRead 不是以相同的方法调用的。
DispatchRaiseReceive 方法如下所示:
private void DispatchRaiseReceived(byte[] data)
{
dispatcher.BeginInvoke((ReceiverCallback)RaiseReceived, socket.Client.RemoteEndPoint, data);
}
其中套接字是 TcpClient 对象。
分散的方法类似于以下代码。这样做只是通过事件传递数据以进行进一步处理。
private void RaiseReceived(IPEndPoint sender, byte[] data)
{
if(IsEnabled){
if (Received != null)
{
Received(this, new TCPDataArgs(sender, data));
}
}
}
永远不会调用调度程序需要调用的实际方法。现在,从我在网上能够找到的内容来看,它可能与调度程序未在正确的线程上创建有关,因此它永远不会在正确的线程上调用该方法。但是,调度程序是在我的线程上创建的,因此这应该不适用。
为了解决这个问题,我明确地从我的 UI-Thread 中获取了Dispatcher
,并将其传递给我想使用它的所需位置。而不是试图用Dispatcher.CurrentDispatcher
来获得它.你知道什么,它奏效了。现在正在正确调用委托。
显然Dispatcher.CurrentDispatcher
没有得到我希望它使用的正确Dispatcher
。