调度程序派遣的代表永远不会被解雇

本文关键字:永远 调度程序 | 更新日期: 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