在 WCF 项目中使用回调时遇到一些问题。
首先,服务器调用Foo
客户端上的一些函数,然后将请求转发到 Windows 窗体 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();
图形界面类
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()
在调用no之前如何确保Foo()
当前正在执行?