0

在 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()当前正在执行?

4

1 回答 1

0

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

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

于 2010-05-27T00:46:35.360 回答