获取回调通道时抛出NullReference异常

时间:2010-04-08 20:56:46

标签: wcf callback nullreferenceexception duplex contract

我正在尝试与WCF的双工合同相处。本文的代码

http://msdn.microsoft.com/en-us/library/ms731184.aspx

ICalculatorDuplexCallback callback = null; callback = OperationContext.Current.GetCallbackChannel();

抛出NullReferenceException。那么我该如何管理呢?

感谢您的关注!

2 个答案:

答案 0 :(得分:0)

您是否为ICalculatorDuplex设置了界面

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required,
                 CallbackContract=typeof(ICalculatorDuplexCallback))]

当一个服务收到一条消息时,它会查看消息中的replyTo元素来确定回复的位置,我猜想如果你错过了回调契约属性,它会导致你得到一个NullReferenceException,因为它没有不知道在哪里回复。

答案 1 :(得分:0)

我刚刚完成了这个例子。

我的服务代码是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;

namespace DuplexExample
{
    // Define a duplex service contract.
// A duplex contract consists of two interfaces.
// The primary interface is used to send messages from client to service.
// The callback interface is used to send messages from service back to client.
// ICalculatorDuplex allows one to perform multiple operations on a running result.
// The result is sent back after each operation on the ICalculatorCallback interface.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required,
                 CallbackContract=typeof(ICalculatorDuplexCallback))]
public interface ICalculatorDuplex
{
    [OperationContract(IsOneWay=true)]
    void Clear();
    [OperationContract(IsOneWay = true)]
    void AddTo(double n);
    [OperationContract(IsOneWay = true)]
    void SubtractFrom(double n);
    [OperationContract(IsOneWay = true)]
    void MultiplyBy(double n);
    [OperationContract(IsOneWay = true)]
    void DivideBy(double n);
}

// The callback interface is used to send messages from service back to client.
// The Equals operation will return the current result after each operation.
// The Equation opertion will return the complete equation after Clear() is called.
public interface ICalculatorDuplexCallback
{
    [OperationContract(IsOneWay = true)]
    void Equals(double result);
    [OperationContract(IsOneWay = true)]
    void Equation(string eqn);
}
// Service class which implements a duplex service contract.
// Use an InstanceContextMode of PerSession to store the result
// An instance of the service will be bound to each duplex session
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class CalculatorService : ICalculatorDuplex
{
    double result;
    string equation;
    ICalculatorDuplexCallback callback = null;

    public CalculatorService()
    {
        result = 0.0D;
        equation = result.ToString();
        callback = OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();
    }

    public void Clear()
    {
        callback.Equation(equation + " = " + result);
        result = 0.0D;
        equation = result.ToString();
    }

    public void AddTo(double n)
    {
        result += n;
        equation += " + " + n;
        callback.Equals(result);
    }

    public void SubtractFrom(double n)
    {
        result -= n;
        equation += " - " + n;
        callback.Equals(result);
    }

    public void MultiplyBy(double n)
    {
        result *= n;
        equation += " * " + n;
        callback.Equals(result);
    }

    public void DivideBy(double n)
    {
        result /= n;
        equation += " / " + n;
        callback.Equals(result);
    }

}
class Program
{
    static void Main()
    {
        var host = new ServiceHost(typeof(CalculatorService));

        host.Open();
        Console.WriteLine("Service is open");
        Console.ReadLine();

    }
}

}

我的应用程序配置如下:

<?xml version="1.0" encoding="utf-8" ?>

                                                                                                       

    <services>
        <service behaviorConfiguration="NewBehavior" name="DuplexExample.CalculatorService">
            <endpoint address="dual" binding="wsDualHttpBinding" bindingConfiguration=""
                contract="DuplexExample.ICalculatorDuplex" />
            <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
                contract="IMetadataExchange" />
            <host>
                <baseAddresses>
                    <add baseAddress="http://localhost:8081/duplex" />
                </baseAddresses>
            </host>
        </service>
    </services>
</system.serviceModel>

然后我使用配置文件中的主机地址创建名为CalculatorService的服务引用。

所以我的客户看起来像:

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using Client.CalculatorService;


namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
          var context = new InstanceContext(new CallbackHandler());

            var client = new CalculatorDuplexClient(context);

            Console.WriteLine("Press <ENTER> to terminate client once the output is displayed.");
            Console.WriteLine();


            // Call the AddTo service operation.
            var value = 100.00D;
            client.AddTo(value);

            // Call the SubtractFrom service operation.
            value = 50.00D;
            client.SubtractFrom(value);

            // Call the MultiplyBy service operation.
            value = 17.65D;
            client.MultiplyBy(value);

            // Call the DivideBy service operation.
            value = 2.00D;
            client.DivideBy(value);

            // Complete equation
            client.Clear();

            Console.ReadLine();

            //Closing the client gracefully closes the connection and cleans up resources
            client.Close();
        }
    }


    // Define class which implements callback interface of duplex contract
    public class CallbackHandler : ICalculatorDuplexCallback
    {
        public void Result(double result)
        {
            Console.WriteLine("Result({0})", result);
        }

        public void Equation(string eqn)
        {
            Console.WriteLine("Equation({0})", eqn);
        }


        #region ICalculatorDuplexCallback Members

        public void Equals(double result)
        {
            Console.WriteLine("Equals{0} ",result );
        }

        #endregion
    }
}