シリアルポート(たとえばCOM1)からデータを常に読み取る必要のあるシリアルポートコードがあります。しかし、これは非常にCPU集約的で、ユーザーがウィンドウを動かしたり、シリアル・ラインを介して受信されたバイトなどの多くのデータがウィンドウに表示されていると、通信が乱れてしまいます。次のコードを考慮System.IO.Ports.SerialPortとマルチスレッド
:
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] buffer = new byte[port.ReadBufferSize];
var count = 0;
try
{
count = port.Read(buffer, 0, buffer.Length);
}
catch (Exception ex)
{
Console.Write(ex.ToString());
}
if (count == 0)
return;
//Pass the data to the IDataCollector, if response != null an entire frame has been received
var response = collector.Collect(buffer.GetSubByteArray(0, count));
if (response != null)
{
this.OnDataReceived(response);
}
コードは、データのストリームが 一定であり、データ(フレーム/パケット)について分析されなければならないように収集することが必要です。
port = new SerialPort();
//Port configuration code here...
this.collector = dataCollector;
//Event handlers
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
ウィンドウに追加されたユーザーとの対話と何が存在しない場合は、 これは、すぐに通信が本当にめちゃくちゃます相互作用があると正常に動作しますが。
Dispatcher.BeginInvoke(new Action(() =>
{
var builder = new StringBuilder();
foreach (var r in data)
{
builder.AppendFormat("0x{0:X} ", r);
}
builder.Append("\n\n");
txtHexDump.AppendText(builder.ToString());
txtHexDump.ScrollToEnd();
}),System.Windows.Threading.DispatcherPriority.ContextIdle);
});
をしかし、たとえ簡単な呼び出しが原因の問題をlog4netのために: タイムアウトは、例えば
....などが発生、これがすべてを台無しに。
はSERIALPORT通信 を最適化するために、任意のベストプラクティスはありますか誰かが私が間違ってやっているものを私に伝えることができます...
更新:場合
上記の多くのローミングサービスをしませんでした。私は非常に単純な(そして愚かな)少し例を作った:
class Program
{
static void Main(string[] args)
{
var server = new BackgroundWorker();
server.DoWork += new DoWorkEventHandler(server_DoWork);
server.RunWorkerAsync();
var port = new SerialPort();
port.PortName = "COM2";
port.Open();
string input = "";
Console.WriteLine("Client on COM2: {0}", Thread.CurrentThread.ManagedThreadId);
while (input != "/quit")
{
input = Console.ReadLine();
if (input != "/quit")
{
var data = ASCIIEncoding.ASCII.GetBytes(input);
port.Write(data, 0, data.Length);
}
}
port.Close();
port.Dispose();
}
static void server_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("Listening on COM1: {0}", Thread.CurrentThread.ManagedThreadId);
var port = new SerialPort();
port.PortName = "COM1";
port.Open();
port.ReceivedBytesThreshold = 15;
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
}
static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var port = (SerialPort)sender;
int count = 0;
byte[] buffer = new byte[port.ReadBufferSize];
count = ((SerialPort)sender).Read(buffer, 0, buffer.Length);
string echo = ASCIIEncoding.ASCII.GetString(buffer,0,count);
Console.WriteLine("-->{1} {0}", echo, Thread.CurrentThread.ManagedThreadId);
}
}
結果は次のようになります。
がCOM1に聞く:6 クライアントCOM2上:10 これは私が送っていくつかのサンプルデータであり、 ---> 6これは私がメインスレッド上で発生
だからポートからデータを読み取る送るいくつかのサンプルデータ....
が、これは私の問題を引き起こしているものの一部である可能性がありますがありますか?
コードの最後のセクションはどこですか? 'データ'変数はどこから来ますか? –
上記のコードは、IDataCollectorがイベントを発生させてフル・フレームのデータを収集したことを示すときに呼び出されます。それはWPF Windowsにあります。しかし、IDataTransportServerまたはIDataCollector実装のコードにlog.Warn( ".....")ステートメントを追加しても、SerialCommunicationは不正になります... 「データ」は、シリアルから読み込んだものです buffer.GetSubByteArray(0、count) – TimothyP
ちょうどどのコードであっても、シリアル通信が間違ってしまう... – TimothyP