由调度员派遣的代表绝不会被解雇

发布于 2025-01-03 03:57:40 字数 1524 浏览 0 评论 0原文

我正在尝试触发一个方法作为 NetworkStream 上的异步读取操作的结果。读取操作是通过 BeginRead 和 EndRead 完成的,导致 EndRead 在 BeginRead 指定的回调中被调用。所有非常基本的东西。现在,由于回调是在系统生成的线程中完成的,因此从 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 的全局私有 byte[],因为 BeginRead 和 EndRead 不是在同一个方法中调用的。

DispatchRaiseReceive 方法如下所示:

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

其中socket 是TcpClient 对象。

调度的方法类似于以下代码。其作用只是通过事件传递数据以进行进一步处理。

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

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

I am trying to fire a method as a result to an asynchronous read operation on a NetworkStream. The read operation is done via BeginRead and EndRead, resulting in the EndRead being called in the callback specified with BeginRead. All pretty basic stuff. Now, as the callback is done in a system generated Thread, the data read from the NetworkStream is no longer owned by my thread, that called the BeginRead. To overcome that, I wrote a method to further process the data read, which I try to call via my Thread's dispatcher.

// These are created in my Thread
private delegate void ReceiverCallback(IPEndPoint sender, byte[] data);
private Dispatcher dispatcher = Dispatcher.CurrentDispatcher;

With the callback looking like this:

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();
}

The DataReceivedStruct is a simple struct holding the NetworkStream and an AutoResetEvent.
ReadBuffer is a global private byte[] of 1024 length, as BeginRead and EndRead aren't called in the same method.

The DispatchRaiseReceive method looks like this:

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

Where socket is a TcpClient object.

The disptached method looks like the following bit of code. What this does is simply pass the data along via an event for further processing.

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

The actual method that the dispatcher needs to call, is never called. Now from what I've been able to find on the web is that it could have something to do with the dispatcher not being created on the correct Thread, and thus it is never invoking the method on the correct Thread. However, the dispatcher is created on my Thread, so that shouldn't apply.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤城病女 2025-01-10 03:57:40

为了解决这个问题,我从 UI 线程中显式获取了 Dispatcher,并将其传递到我想要使用它的所需位置。这而不是尝试使用 Dispatcher.CurrentDispatcher 获取它。你知道吗,它成功了。现在可以正确调用代表。

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

As an attempt to fix this, I explicitly got the Dispatcher from my UI-Thread, and passed that along to the desired place I wanted to use it. This instead of trying to get it with Dispatcher.CurrentDispatcher. And what do you know, it worked. The delegate is now being called correctly.

Apparently Dispatcher.CurrentDispatcher didn't get the correct Dispatcher I wanted it to use.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文