调度员派遣的代表从未被解雇

时间:2012-02-08 10:04:59

标签: c# wpf delegates dispatcher

我试图将一个方法作为结果触发到NetworkStream上的异步读取操作。读取操作通过BeginRead和EndRead完成,从而导致在使用BeginRead指定的回调中调用EndRead。所有非常基本的东西。现在,当回调在系统生成的Thread中完成时,从NetworkStream读取的数据不再由我的线程拥有,该线程调用BeginRead。为了解决这个问题,我编写了一个方法来进一步处理数据读取,我尝试通过我的Thread调度程序调用它。

// 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长度的全局私有byte [],因为BeginRead和EndRead不会在同一方法中调用。

DispatchRaiseReceive方法如下所示:

private void DispatchRaiseReceived(byte[] data)
{
    dispatcher.BeginInvoke((ReceiverCallback)RaiseReceived, socket.Client.RemoteEndPoint, data);
}

其中socket是TcpClient对象。

disptached方法看起来像下面的代码。这样做只是通过事件传递数据以进行进一步处理。

private void RaiseReceived(IPEndPoint sender, byte[] data)
{
    if(IsEnabled){
        if (Received != null)
        {
            Received(this, new TCPDataArgs(sender, data));
        }
    }
}

调度程序需要调用的实际方法永远不会被调用。现在我可以在网上找到它可能与调度程序没有在正确的Thread上创建有关,因此它永远不会在正确的Thread上调用该方法。但是,调度程序是在我的线程上创建的,因此不应该应用。

1 个答案:

答案 0 :(得分:0)

为了解决这个问题,我明确地从我的UI-Thread获得了Dispatcher,并将其传递到我想要使用它的所需位置。而不是尝试使用Dispatcher.CurrentDispatcher来获取它。你知道什么,它有效。现在正在正确调用委托。

显然Dispatcher.CurrentDispatcher没有得到我希望它使用的正确Dispatcher