我读了一些关于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)