WCF对象中的“System.NullReferenceException未处理”

时间:2011-04-11 12:43:04

标签: c# wcf

仍然在使用我的wcf应用程序的服务器部分。

问题是在服务器类中创建“回调”对象会导致“System.NullReferenceException未处理”错误。

如果我理解正确,它会在我创建此服务器对象时发生 - ServerClass myServer = new ServerClass();

所以我想我应该以某种方式为服务器对象创建一个列表并创建&每当客户端建立连接时自动添加此对象。请建议,最好的方法是什么?

到目前为止,这是我的代码:

namespace server2
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
            myServer.eventHappened += new EventHandler(eventFunction);
        }

        ServerClass myServer = new ServerClass();
        // here I instance a new server object.
        // yet I believe that I need to make a list, that would store this objects, so that multiple clients would be able to connect,
        // and I would be able to pick, to whom I want to send a callback.

        void eventFunction(object sender, EventArgs e)
        {
            label1.Text = myServer.clientName;
        }

        private ServiceHost duplex;

        private void Form2_Load(object sender, EventArgs e)     /// once the form loads, create and open a new ServiceEndpoint.
        {
            duplex = new ServiceHost(typeof(ServerClass));
            duplex.AddServiceEndpoint(typeof(IfaceClient2Server), new NetTcpBinding(), "net.tcp://localhost:9080/service");
            duplex.Open();
            this.Text = "SERVER *on-line*";
        }

    }




    class ServerClass : IfaceClient2Server
    {

        public event EventHandler eventHappened;

        IfaceServer2Client callback = OperationContext.Current.GetCallbackChannel<IfaceServer2Client>();
        // ERROR: System.NullReferenceException was unhandled

        public string clientName = "noname";

        public void StartConnection(string name)
        {
            clientName = name;
            MessageBox.Show(clientName + " has connected!");

            eventHappened(this, new EventArgs());
            // ERROR: System.NullReferenceException was unhandled :(

            callback.Message_Server2Client("Welcome, " + clientName);
        }

        public void Message_Cleint2Server(string msg)
        {
        }

        public void Message2Client(string msg)
        {
        }

    }




    [ServiceContract(Namespace = "server", CallbackContract = typeof(IfaceServer2Client), SessionMode = SessionMode.Required)]


    public interface IfaceClient2Server           ///// what comes from the client to the server.
    {
        [OperationContract(IsOneWay = true)]
        void StartConnection(string clientName);

        [OperationContract(IsOneWay = true)]
        void Message_Cleint2Server(string msg);
    }


    public interface IfaceServer2Client          ///// what goes from the sertver, to the client.
    {
        [OperationContract(IsOneWay = true)]
        void AcceptConnection();

        [OperationContract(IsOneWay = true)]
        void RejectConnection();

        [OperationContract(IsOneWay = true)]
        void Message_Server2Client(string msg);
    }

}

谢谢!

2 个答案:

答案 0 :(得分:2)

这不可能那样做。首先,回调通道仅在操作中可用,而不是在创建服务类的实例时。

其次,您的ServerClass的实例由WCF服务主机创建,具体取决于您的WCF配置。例如,每次调用可能有一个实例(!)。因此,自己创建实例并附加事件处理程序不会影响自动创建的实例。这就是你在StartConnection中获得例外的原因。

在这种情况下我要做的是:

  1. 创建一个发布所需事件的单例类
  2. 在主代码中附加处理程序到事件。这将是侦听事件的代码
  3. 创建一个提升事件的公共方法(如ConnectionStarted
  4. ServerClass
  5. 中调用此方法

    如果您不需要等待事件处理程序完成,您还可以在单​​独的线程中异步引发事件。然后,您必须确保在步骤2)中附加的事件处理程序使用例如this.Invoke(表单)或this.Dispatcher.BeginInvoke(WPF)正确处理线程上下文。

答案 1 :(得分:0)

尝试将该行放在类构造函数中:

class ServerClass : IfaceClient2Server
{
   public event EventHandler eventHappened;
   IfaceServer2Client callback;

   public ServerClass ()
   {
      callback = OperationContext.Current.GetCallbackChannel<IfaceServer2Client>();
   }

   ...
}

如果仍然没有运气,这可能意味着您只能在某些操作中使用OperationContext.Current