【问题标题】:Ensuring that all callbacks were completed before sending a new request through a DuplexChannel using WCF确保在使用 WCF 通过 DuplexChannel 发送新请求之前完成所有回调
【发布时间】:2010-05-26 19:57:14
【问题描述】:

我在 WCF 项目中使用回调时遇到了一些问题。

首先,服务器调用客户端上的某个函数Foo,然后将请求转发到 Windows 窗体 GUI:

GUI类

delegate void DoForward();
public void ForwardToGui() {
    if (this.cmdSomeButton.InvokeRequired) {
        DoForward d = new DoForward(ForwardToGui);
            this.Invoke(d);
        }
        else {
            Process(); // sets result variable in callback class as soon as done
        }
    }
}

回调类

object _m = new object();
private int _result;
public int result {
    get { return _result; }
    set {
        _result = value; 
        lock(_m) {
            Monitor.PulseAll(_m);
        }
    }
}

[OperationContract]
public int Foo() {
    result = 0;
    Program.Gui.ForwardToGui();
    lock(_m) {
        Monitor.Wait(_m, 30000);
    }
    return result;
}

现在的问题是用户应该可以取消进程,但不能正常工作:

服务器接口

[OperationContract]
void Cleanup();

GUI类

private void Gui_FormClosed(object sender, EventArgs e) {
    Program.callbackclass.nextAction = -1; 
    // so that the monitor pulses and Foo() returns
    Program.server.Cleanup();
}

问题在于Cleanup() 挂起。但是,当我在Process() 未运行时关闭表单时,它可以正常工作。

来源似乎是在监视器脉冲等之前调用了Cleanup(),因此在服务器的最后一个请求尚未得到响应之前向服务器发送了一个新请求。

我该如何解决这个问题?在调用Cleanup() 之前如何确保当前没有正在执行Foo()

【问题讨论】:

  • 我很困惑试图将代码的 sn-ps 拼凑在一起。两个代码 sn-ps 是否在同一个 GUI 类中以“GUI 类”为标题?我看到的第一个警告是您正在调用 System.Windows.Form.Invoke 而不是 System.Windows.Forms.BeginInvoke。这是故意的吗?
  • 标有 GUI 类的两个部分是同一个类。我现在正在努力。似乎 BeginInvoke 完成了这项工作!谢谢 :-) 您介意再次发表您的评论作为答案吗?

标签: c# wcf winforms duplex


【解决方案1】:

我看到的第一个警告是您正在调用 Invoke 而不是 BeginInvoke

Invoke 等到其他线程上的操作完成后才返回,这在某些情况下可能会导致死锁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多