我有一个通过USB连接到串口的刻度(但我也使用过直接串口并遇到过这个问题)
我启动我的应用程序并打电话给SerialPort.Open
并且它打开正常,根据电话...但是,当我按照附加的比例推送打印时,我没有得到我设置的队列中的任何内容。然后,大约20-30秒后,我能够推送打印,所有打印都很好。
为了增加混乱,我可以随时通过同一个端口打开并打印到PuTTy。
显然我的代码中缺少一些东西。这里的Output队列带有在程序打开时设置的观察者:
public class Scan_Output_Queue<T> : AFGObservableAFGObserver<T,T>, IEnumerable<T>
{
private ConcurrentQueue<T> _Queue;
public Scan_Output_Queue()
{
_Queue = new ConcurrentQueue<T>();
}
public T Dequeue()
{
T item = default(T);
_Queue.TryDequeue(out item);
return item;
}
public void reinsert(T item)
{
Queue<T> queueCopy = new Queue<T>(_Queue.ToArray());
T junk = default(T);
foreach (T weight in queueCopy)
{
_Queue.TryDequeue(out junk);
}
_Queue.Enqueue(item);
foreach (T weight in queueCopy)
{
_Queue.Enqueue(weight);
}
base.redraw_Send();
}
public void Enqueue(T Item)
{
_Queue.Enqueue(Item);
}
public T Peek()
{
T item = default(T);
_Queue.TryPeek(out item);
return item;
}
protected override T Receive(T value)
{
Enqueue(value);
return value;
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _Queue.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _Queue.GetEnumerator();
}
}
我在这里放置断点,但在20-30秒的标记处没有任何'神奇'。我只能按下打印按钮,它就会填满队列。
这是请求的Scale Reader代码。这持续循环尝试打开端口20-30秒:
Public Class Scale_Reader
Public Property Setting_Port As String
Public Property Setting_Baud As Integer
Public Property Setting_Parity As System.IO.Ports.Parity
Public Property Setting_DataBits As Integer
Public Property Setting_StopBits As Integer
Public Property Setting_Suffix As String
Public Property LineSeperator As String = vbCrLf
Public Property LineSeperator As String = Setting_Suffix
Public Sub New(ByVal sPort As String, ByVal sBaud As Integer, ByVal sPari_Str As String, ByVal sDataBits As Integer, ByVal sStopBits As Integer, sSuffix As String)
Setting_Port = sPort
Setting_Baud = sBaud
Select Case sPari_Str
Case "e"
Setting_Parity = IO.Ports.Parity.Even
Case "m"
Setting_Parity = IO.Ports.Parity.Mark
Case "n"
Setting_Parity = IO.Ports.Parity.None
Case "o"
Setting_Parity = IO.Ports.Parity.Odd
Case "s"
Setting_Parity = IO.Ports.Parity.Space
End Select
Setting_DataBits = sDataBits
Setting_StopBits = sStopBits
If sSuffix.ToUpper() = "CR" Then
LineSeperator = vbCr
Else If sSuffix.ToUpper() = "CRLF" Then
LineSeperator = vbCrLf
Else
LineSeperator = ""
End If
End Sub
Public Property PrintString As String
Public Property ValidExpressions As List(Of String) = New List(Of String)
Public Property InvalidExpressions As List(Of Scale_InvalidExpression) = New List(Of Scale_InvalidExpression)
Protected Sub Add_ValidExpression(ByVal Expression As String)
ValidExpressions.Add(Expression)
End Sub
Protected Sub Add_InvalidExpression(ByVal Expression As String, ByVal ErrorMessage As String)
Dim I As Scale_InvalidExpression = New Scale_InvalidExpression()
I.Expression = Expression
I.ErrorMessage = ErrorMessage
InvalidExpressions.Add(I)
End Sub
Public Function ReadWeight(Optional GetMode As Integer = 1) As Scale_ReadResults
Dim Results As Scale_ReadResults = Nothing
For i As Integer = 1 To 3
Results = ReadWeightPrivate(GetMode)
If Results.Valid OrElse Results.ErrorMessage <> "" Then
Exit For
End If
Next
Return Results
End Function
Public Property Cancel_ConstantRead As Boolean = False
Public Sub ReadWeightConstant(WeightRead As Action(Of Decimal))
Using Cons_ComPort As SerialPort = New SerialPort()
Dim ReturnWeight As Decimal = 0
Dim data As String = ""
Cancel_ConstantRead = False
While Not Cons_ComPort.IsOpen
InitializeComPort(Cons_ComPort)
End While
While Not Cancel_ConstantRead
If Not Cons_ComPort.IsOpen Then
InitializeComPort(Cons_ComPort)
End If
Try
While Cons_ComPort.BytesToRead > 0
Dim TempData As String = Cons_ComPort.ReadExisting()
data += TempData
Threading.Thread.Sleep(10)
End While
Catch ex As Exception
'InitializeComPort(Cons_ComPort)
End Try
'Find whole lines
Dim Pos As Integer = data.IndexOf(LineSeperator)
'Dim Pos As Integer = data.IndexOf(vbCr)
While Pos > -1
Dim Line As String = data.Substring(0, Pos)
ReturnWeight = TestValidExpressions(Line)
If ReturnWeight <> 0 Then
'Results.Valid = True
'Results.ErrorMessage = ""
'Results.Weight = ReturnWeight
'Results.RawData = data
WeightRead.Invoke(ReturnWeight)
End If
data = data.Substring(Pos + LineSeperator.Length)
'data = data.Substring(Pos + 1)
Pos = data.IndexOf(vbCr)
End While
Threading.Thread.Sleep(10)
End While
If Cons_ComPort.IsOpen Then
GC.ReRegisterForFinalize(Cons_ComPort.BaseStream)
Cons_ComPort.Close()
GC.ReRegisterForFinalize(Cons_ComPort)
End If
End Using
End Sub
Private Function ReadWeightPrivate(GetMode As Integer) As Scale_ReadResults
Dim Results As Scale_ReadResults = New Scale_ReadResults()
Dim ReturnWeight As Decimal = 0
Dim Attempts As Integer = 20
Using ComPort As SerialPort = New SerialPort()
Try
InitializeComPort(ComPort)
Catch
Dim ErrorMessage As String = "Invalid Comm Settings."
Results.ErrorMessage = ErrorMessage
Return Results
End Try
ComPort.ReadExisting()
If GetMode = 1 Then
ComPort.Write(PrintString)
Attempts = 100
End If
Dim NumTries As Integer = 0
Dim data As String = ""
While NumTries < Attempts
While ComPort.BytesToRead > 0
data += ComPort.ReadExisting.Replace(Chr(10), " ").Replace(Chr(13), " ")
End While
ReturnWeight = TestValidExpressions(data)
If ReturnWeight <> 0 Then
Results.Valid = True
Results.ErrorMessage = ""
Results.Weight = ReturnWeight
Results.RawData = data
Exit While
End If
Dim ErrorMessage As String = TestInValidExpressions(data)
If GetMode = 1 AndAlso ErrorMessage.Length > 0 Then
Results.Valid = False
Results.ErrorMessage = ErrorMessage
Results.Weight = 0
Results.RawData = data
Exit While
End If
Threading.Thread.Sleep(10)
NumTries += 1
Results.RawData = data
End While
ComPort.Close()
End Using
Return Results
End Function
Private Function TestValidExpressions(ByVal Data As String) As Decimal
For Each ValidExpression As String In ValidExpressions
Dim R As New Regex(ValidExpression)
Dim M As Match = R.Match(Data)
If M.Success Then
Dim sWeight = M.Groups("Weight").Value
Return Val(sWeight)
End If
Next
Return 0
End Function
Private Function TestInValidExpressions(ByVal Data As String) As String
For Each ValidItem As Scale_InvalidExpression In InvalidExpressions
Dim R As New Regex(ValidItem.Expression)
Dim M As Match = R.Match(Data)
If M.Success Then
Return ValidItem.ErrorMessage
End If
Next
Return ""
End Function
Private Sub InitializeComPort(ByRef ComPort As SerialPort)
ComPort.PortName = Setting_Port
ComPort.BaudRate = Setting_Baud
ComPort.Parity = Setting_Parity
ComPort.StopBits = Setting_StopBits
ComPort.DataBits = Setting_DataBits
ComPort.Handshake = Handshake.None
Try
GC.SuppressFinalize(ComPort)
ComPort.Open()
GC.SuppressFinalize(ComPort.BaseStream)
Catch ex As Exception
' MessageWindow.Show("COM Port Error", "The COM Port cannot be opened, please check connection", MessageWindow.ButtonStyle.Ok, MessageWindow.IconStyle.Error)
End Try
End Sub
End Class