2011-04-11 60 views
1

仍在我的wcf應用程序的服務器部分掙扎。WCF對象中的「System.NullReferenceException未處理」

問題是,在服務器類內創建一個「回調」對象,導致「System.NullReferenceException was unhandled」錯誤。

如果我理解正確,它發生在我創建此服務器對象時 - 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

這不能這樣做。首先,回調通道只在一個操作中可用,而不是在創建服務類的實例時。

其次,您的ServerClass的實例由WCF服務主機根據您的WCF配置創建。例如,每個呼叫(!)可能有一個實例。因此,自己創建實例並附加事件處理程序不會影響自動創建的實例。這就是爲什麼你在StartConnection中遇到異常。

我想在這種情況下,做的是:

  1. 創建發佈所需事件
  2. 從你的主代碼中附加的處理程序對該事件的單例類。這將是監聽事件
  3. 創建一個公共方法的代碼(如ConnectionStarted),這引發該事件
  4. 調用此方法從ServerClass

如果您不需要等待事件處理程序完成後,還可以在單​​獨的線程中異步提升事件。然後您必須確保步驟2)中附加的事件處理程序使用例如this.Invoke(Forms)或this.Dispatcher.BeginInvoke(WPF)正確處理線程上下文。

0

嘗試把該線路在類的構造函數:

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

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

    ... 
} 

如果仍然沒有運氣這可能意味着你可以使用OperationContext.Current只有裏面的一些操作。

+0

nope,在callback = OperationContext.Current.GetCallbackChannel ();方法上相同的「System.NullReferenceException未處理」。和eventHappened(this,new EventArgs()); – Roger 2011-04-11 13:16:20

+0

所以就像我說的,你的邏輯需要重新思考,因爲'OperationContext.Current'本身是'null' - 參見Thorsten的答案。 :) – 2011-04-11 13:30:05

相關問題