wcf服务计时器混淆

时间:2015-08-31 19:26:07

标签: c# wcf timer serial-port

我读了一些关于wcf和计时器的问题,但它没有帮助只是喷射。

我得到了以下场景。我在Windows服务中托管了一个wcf服务。

wcf-service有一个SerialPort实例,并连接到连接到端口的设备。现在我还有一个定时器,可以正常地向设备发送数据。

当我第一次连接到wcf-service并启动所有内容时,它可以工作。遗憾的是,当我重新启动客户端并拨打电话时,我得到了一个例外。我然后考虑了我的情况,并决定,我需要某种singleton-wfc服务,在所有情况下只获得一次实例化,所以我的电脑永远不会尝试打开相同的SerialPort两次。然后我讨论了[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]。可悲的是,一旦我设置InstanceContextMode.Single,我就会得到“System.ServiceModel.FaultException”Exeptions,我现在甚至无法调用一次。

让我给你看一些代码。

首先,我得到了ServiceContract

public enum Side { Left, Right };

[ServiceContract]
public interface IColorService
{
    [OperationContract]
    void setColor(Color color, Side side);
    [OperationContract]
    Color getColor(Side side);
    [OperationContract]
    void setEnable(bool enable, Side side);
    [OperationContract]
    bool getEnable(Side side);
    [OperationContract]
    void setColorCalculator(FullRangeFader colorCalculator, Side side);
}

这是我的WCF服务实施

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class ColorService : IColorService
{
    bool leftEnable = false;
    bool rightEnable = false;

    Color leftColor;
    Color rightColor;

    FullRangeFader leftColorCalculator = new FullRangeFader();
    FullRangeFader rightColorCalculator = new FullRangeFader();

    Timer timer = new Timer(16); // 100 Herz

    System.IO.Ports.SerialPort serialPort1;

    public ColorService() {
        timer.Elapsed += new ElapsedEventHandler(onTimer);
        timer.Enabled = true;
    }

    private void onTimer(object sender, ElapsedEventArgs e)
    {
        if (leftEnable && leftColorCalculator != null)
            leftColor = leftColorCalculator.advance();
        if (rightEnable && rightColorCalculator != null)
            rightColor = rightColorCalculator.advance();
        sendData();
    }

    public void setColorCalculator(FullRangeFader colorCalculator, Side side) {
        switch (side)
        {
            case Side.Left:
                leftColorCalculator = colorCalculator;
                break;
            case Side.Right:
                rightColorCalculator = colorCalculator;
                break;
        }
    }

    public void setEnable(bool enable, Side side) {
        switch (side)
        {
            case Side.Left:
                this.leftEnable = enable;
                break;
            case Side.Right:
                this.rightEnable = enable;
                break;
        }

        if (!rightEnable && !leftEnable)
            timer.Enabled = false;
        else
            timer.Enabled = true;
    }

    public bool getEnable(Side side) {
        switch (side)
        {
            case Side.Left:
                return leftEnable;
            default:
                return rightEnable;
        }
    }

    public Color getColor(Side side)
    {
        switch (side)
        {
            case Side.Left:
                return leftColor;
            default:
                return rightColor;
        }
    }

    public void setColor(Color color, Side side)
    {
        switch (side)
        {
            case Side.Left:
                leftColor = color;
                break;
            default:
                rightColor = color;
                break;
        }
        sendData();
    }

    private void initSerialPort() {
        if (serialPort1 == null) { 
            serialPort1 = new System.IO.Ports.SerialPort();
            serialPort1.PortName = "COM4";
            serialPort1.Open();
        }
    }

    private void sendData()
    {
        initSerialPort();

        byte[] buf = { leftColor.R, leftColor.G, leftColor.B, rightColor.R, rightColor.G, rightColor.B };
        serialPort1.Write(buf, 0, 6);

        serialPort1.Close();
    }
}

最后有我的DataContract-Class,我想在我的客户端中创建FullRangeFader对象。正如您所看到的,我计划创建一个名为ColorCalculator的父类,因此我可以将不同的类传递给我的服务,以进行不同的计算。但我还没明白,如何做那种喷射的东西。

[DataContract] 
public class FullRangeFader //: ColorCalculator
    {
        enum State
        {
            Start, RG, G, GB, B, BR, R
        }

        State state = State.Start;

        Color color = Color.FromArgb(0, 0, 0);

        public Color advance() // override
        {
            switch (state)
            {
                // doing fancy calculations
            }
            return color;
        }
    }

最后在我的客户端内,我可以使用wcf-service,如:

        ServiceReference.ColorServiceClient client = new ServiceReference.ColorServiceClient("BasicHttpBinding_IColorService");

        colorDialog1.ShowDialog();
        client.setColor(colorDialog1.Color, Side.Left);

        client.setColorCalculator(new FullRangeFader(), Side.Left);
        client.setEnable(true, Side.Left);

这是我收到错误的地方。我希望得到一些帮助...这是我不仅仅使用wcf而是使用c#的第一件事。感谢。

错误的Stacktrace:

bei System.IO.Ports.SerialPort.Write(Byte [] buffer,Int32 offset,Int32 count)    bei ClassLibrary.ColorService.sendData()在C:\ Users \ jonas \ Documents \ Visual Studio 2015 \ Projects \ LED \ ClassLibrary \ ColorService.cs:Zeile 118。    bei ClassLibrary.ColorService.setColor(颜色,侧面)在C:\ Users \ jonas \ Documents \ Visual Studio 2015 \ Projects \ LED \ ClassLibrary \ ColorService.cs:Zeile 102中。    bei SyncInvokesetColor(Object,Object [],Object [])    bei System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance,Object [] inputs,Object []& outputs)    bei System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)    bei System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)    bei System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)    bei System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)    bei System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)    bei System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)    bei System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)    bei System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)    bei System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)    bei System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

0 个答案:

没有答案