【问题标题】:C# Strange Behaviour of Delegate Callbacks委托回调的 C# 奇怪行为
【发布时间】:2013-02-08 15:30:14
【问题描述】:

我写了一个类,它应该提供与 NodeJS 服务器的基本交互。此类还包括 TcpClient 实例并异步工作(例如 BeginRead、BeginWrite 等方法),因此许多函数将回调(使用 lambda expr. 的匿名函数)作为参数。问题始于这种情况(我试图说明与原始代码相似的和平)。

this._nodeJS.Send("DATA_TO_SEND", (Response) => {
    Console.WriteLine(Response);

    // Section1
    this._nodeJS.Send("ANOTHER_DATA", (Response1) => {
        Console.WriteLine(Response1);
    });
});

Section1 中出现问题。当它被注释掉时,程序按预期运行。收到写入控制台的响应。当它没有被注释掉时,它开始表现得很奇怪。在 Section1 中写入 Console 不起作用(在许多情况下),重要的是,本节中 Console.WriteLine 下面的代码不会执行,“线程”只是在命令之前停止。我尝试一步步调试它,Section1 中的变量设置正确,当我执行下一个命令时,调试就停止了。这种方法有什么问题吗?有什么需要注意的吗?

为了更好的想象,这里是我的例子。我连接到 NodeJS 服务器,完成后,我发送一个请求并等待包含数据的响应,这些数据经过处理并在下一个请求(第 1 节)中再次发送到 NodeJS 服务器。 NodeJS 给了我最终的回应和程序的工作......感谢您的任何建议!

【问题讨论】:

  • 您是在发送之后和回调之前处理_nodeJS 对象,还是为该变量分配一个新值?尝试在第一个回调中创建一个新的 nodeJS 对象,以便在发送第二个Send 时使用,至少用于诊断,如果不是在您的最终程序中。
  • 感谢您的快速回复。根据我的原始资料,NodeJS 实例以注册表模式存储,因此 NodeJS 只有一个实例。当我调试它并进入section1时,每一个变量都有正确的值,每一个。

标签: c# delegates lambda callback


【解决方案1】:

最后,我想通了,这是怎么回事。我知道,我没有展示我的原始代码,而是使用了某种伪代码,但如果有人有兴趣知道,问题可能是导致接收数据的错误转换。我有大小为 1024 的缓冲区和 StringBuilder 变量,其中附加了数据。所以当我收到数据时,以这种方式转换它:Encoding.UTF8.GetString(state.Buffer) - 这是错误的,我不得不使用Encoding.UTF8.GetString(state.Buffer, 0, bytesRead)。我不知道怎么回事,但这部分代码造成了麻烦并停止执行回调。

【讨论】:

    【解决方案2】:

    在不知道您的实现细节的情况下,我怀疑第二个 _nodeJS.Send(... 调用被第一个 Send 调用的响应阻止了。

    猜测一下,您的代码会执行以下操作(由伪代码组成!):

    void Send(String data, Action<Response> callback)
    {
        _socket.BeginSend(Magic(data), r => {
            callback.Invoke(r.ResponseData);
            _socket.EndSend(r.Result);    //you cannot call _socket.Send() again until you have done this!
        });
    }
    

    由于操作顺序,它应该这样做:

    void Send(String data, Action<Response> callback)
    {
        _socket.BeginSend(Magic(data), r => {
            _socket.EndSend(r.Result);
            callback.Invoke(r.ResponseData);
        });
    }
    

    【讨论】:

    • 谢谢。我就是这样做的。在发送函数中,我在 NetworkStream 上调用 EndWrite,然后调用我的回调。我想强调在成功接收到响应并且所有变量(包括“Response1”变量)包含正确的数据后调用第二个发送函数。问题是,当我在 section1 中找到问题的根源并调试该代码时,执行代码 Console.WriteLine(Response1) 和其他代码的“线程”就停止了。好像被另一个线程阻止了,对我来说真的很奇怪。
    • @TomasPetovsky 如果您只拨打Console.Writeline(); 电话,它会起作用吗?你可以只增加一个整数字段来检查它是否被调用。
    • 是的,它可以工作,我想,Console.WriteLine();在许多情况下,当我使用 Console.WriteLine(); 时开始工作;在当前流程中执行的每个回调函数中。但是我真的不需要 WriteLine 任何东西,它只是为了调试目的,如果 casct 让我感到难过,section1 中的代码(在原始版本中我有 console.writeline 和很多代码行)只是停止执行!它的行为就像它被其他完成的回调或其他东西所阻止一样。我真的不知道。
    猜你喜欢
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多