在此文本下方的代码中,我遇到了问题。这是一段通过 comport 发送字节的代码。但是对于程序的第一个版本(那是用 C++ 编写的,而不是由我编写的),引导文件的发送发生在 5 秒内。在我制作的版本中,它在 46 秒内发送引导文件是 9 倍。
现在有没有人我可以提高速度还是只是.net 4中的一个问题
using System.ComponentModel;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Idento.Common.Tracing;
using Idento.Common.Utilities;
using System;
namespace Communication
{
public class FileTransfer
{
private readonly String _bootFileName;
private readonly String _appFileName;
public int BootFilePercentage { get; private set; }
public int AppFilePercentage { get; private set; }
private BackgroundWorker _worker;
private FileTransferDialog _dialog;
private ComPort _comPort;
private readonly string _port;
private readonly string _baudRate;
public bool Success { get; private set; }
public bool _abort;
public bool _aborted;
public bool _sendingboot;
public FileTransfer(string port, String baudRate, String bootFileName, String appFileName)
{
_port = port;
_baudRate = baudRate;
_bootFileName = bootFileName;
_appFileName = appFileName;
}
public void Run()
{
_worker = new BackgroundWorker();
_dialog = new FileTransferDialog(_worker, this);
_worker.DoWork += Worker;
_worker.RunWorkerCompleted += BackgroundWorkerCompletedEvent;
_worker.RunWorkerAsync();
_dialog.ShowDialog();
}
public void Abort()
{
_abort = true;
}
private void BackgroundWorkerCompletedEvent(object sender, RunWorkerCompletedEventArgs e)
{
// When an exception is generated in the worker we get a new exception here
Object result;
try
{
result = e.Result;
}
catch (Exception exc)
{
MessageBox.Show("Sending files failed: " + exc.InnerException.Message, "", MessageBoxButtons.OK);
_dialog.Close();
return;
}
if (_aborted)
MessageBox.Show("Sending files aborted, Reset programmer.", "", MessageBoxButtons.OK);
else if (Success)
MessageBox.Show("Bootfile and Applicationfile are send succesfully.", "", MessageBoxButtons.OK);
else if (_comPort == null)
MessageBox.Show("Programmer not found at port " + _port, "", MessageBoxButtons.OK);
else
MessageBox.Show("Sending files failed: ", "", MessageBoxButtons.OK);
_dialog.Close();
}
public void Worker(object sender, DoWorkEventArgs doWorkEventArgs)
{
Success = false;
_abort = false;
_aborted = false;
_sendingboot = true;
try
{
_comPort = new ComPort(_port, Int32.Parse(_baudRate));
// Synchronize baudrate with programmer
{
int answer = -1;
int count = 0;
do
{
_comPort.WriteByte(0);
answer = _comPort.ReadByte(50);
if (++count > 100)
throw new Exception("Synchronizing baudrate failed (1)");
} while (answer != 0);
_comPort.WriteByte(0x55);
if (_comPort.ReadByte(200) != 0xaa)
throw new Exception("Synchronizing baudrate failed (2).");
}
if (!_sendingboot)
{
}
SendBootFile();
if (!_aborted)
{
_comPort.Clear();
_comPort.WriteLine("#program");
if (_comPort.ReadByte(200) != 0x06)
throw new Exception("Login failed.");
// version number
for (int x = 0; x < 6; ++x)
if (_comPort.ReadByte(200) == -1)
throw new Exception("Retrieving version number failed.");
_comPort.Clear();
SendApplicationFile();
Success = true;
}
}
catch (IOException)
{
Success = false;
throw new Exception("Communication error");
}
catch (Exception)
{
// MessageBox.Show(exc.ToString());
Success = false;
throw;
}
finally
{
if (_comPort != null)
_comPort.Close();
}
}
private void SendBootFile()
{
// NanoTimer timer = new NanoTimer();
// String result = "";
byte[] array;
try
{
array = File.ReadAllBytes(_bootFileName);
}
catch (IOException)
{
throw new Exception("Error reading boot file");
}
byte hiByte = (byte)(array.Length / 256);
byte lowByte = (byte)(array.Length % 256);
_comPort.WriteByte(hiByte);
_comPort.ReadByte(100);
_comPort.WriteByte(lowByte);
_comPort.ReadByte(100);
int count = 0;
foreach (byte currentByte in array)
{
if (_abort)
{
_aborted = true;
break;
}
++count;
// NanoTimer timer = new NanoTimer();
_comPort.WriteByte(currentByte);
// Thread.Sleep( 1 );
// double time1 = timer.GetMilliseconds();
// timer.Reset();
if (_comPort.ReadByte(100) != currentByte)
throw new Exception("Error sending boot file (1).");
// double time2 = timer.GetMilliseconds();
if (count % 30 == 0 && _worker != null)
{
BootFilePercentage = count * 100 / array.Length;
_worker.ReportProgress(BootFilePercentage);
}
}
_comPort.Clear();
if (!_aborted)
{
if (_worker != null)
{
BootFilePercentage = 100;
_worker.ReportProgress(BootFilePercentage);
}
// Wait for acknowledge, takes more than 5 seconds
int answer = _comPort.ReadByte(20000);
if (answer != 0xaa)
throw new Exception("Error sending boot file (2).");
}
}
private void SendApplicationFile()
{
// NanoTimer timer = new NanoTimer();
StringList list;
// Read file and put it in a list that will be sorted.
try
{
list = new StringList().FromFile(_appFileName);
}
catch (IOException)
{
throw new Exception("Error reading application file.");
}
list.Sort(new SRecordCompare());
/*
StringList testList = new StringList(list.Count);
foreach (var item in list)
testList.Add(item.Substring(0, 4) + " " + item.Substring(4, 4) + " " + item.Substring(8));
testList.ToFile("test.txt");
*/
int count = 0;
foreach (String line in list)
{
if (_abort)
{
_aborted = true;
break;
}
if (!line.StartsWith("S"))
continue;
++count;
// _comPort.WriteLine(line.StartsWith("S9") ? "S9030000FC" : line);
_comPort.WriteLine(line);
// Thread.Sleep(10);
// wait for ACK
int answer = _comPort.ReadByte(2000);
if (answer == -1)
throw new Exception("Timeout waiting for ACK or NAK");
if (answer == 0x15)
throw new Exception("NAK received");
if (answer != 0x06)
throw new Exception(String.Format("Unknown byte {0} received", answer));
if (count % 30 == 0 && _worker != null)
{
AppFilePercentage = count * 100 / list.Count;
_worker.ReportProgress(AppFilePercentage);
}
}
}
}
}
编辑 引导文件的发送发生在这里:
private void SendBootFile()
{
// NanoTimer timer = new NanoTimer();
// String result = "";
byte[] array;
try
{
array = File.ReadAllBytes(_bootFileName);
}
catch (IOException)
{
throw new Exception("Error reading boot file");
}
byte hiByte = (byte)(array.Length / 256);
byte lowByte = (byte)(array.Length % 256);
_comPort.WriteByte(hiByte);
_comPort.ReadByte(100);
_comPort.WriteByte(lowByte);
_comPort.ReadByte(100);
int count = 0;
foreach (byte currentByte in array)
{
if (_abort)
{
_aborted = true;
break;
}
++count;
// NanoTimer timer = new NanoTimer();
_comPort.WriteByte(currentByte);
// Thread.Sleep( 1 );
// double time1 = timer.GetMilliseconds();
// timer.Reset();
if (_comPort.ReadByte(100) != currentByte)
throw new Exception("Error sending boot file (1).");
// double time2 = timer.GetMilliseconds();
if (count % 30 == 0 && _worker != null)
{
BootFilePercentage = count * 100 / array.Length;
_worker.ReportProgress(BootFilePercentage);
}
}
编辑二 这是我拥有的 Comport.cs 类,当你看到这个时,也许你可以帮助我更多。
using System;
using System.IO;
using System.Text;
using System.IO.Ports;
namespace Communication
{
public class ComPort
{
private readonly SerialPort _serialPort;
public ComPort(string portName, int baudRate)
{
_serialPort = new SerialPort();
_serialPort.PortName = portName;
_serialPort.BaudRate = baudRate;
_serialPort.StopBits = StopBits.One;
_serialPort.DataBits = 8;
_serialPort.Parity = Parity.None;
_serialPort.Handshake = Handshake.None;
_serialPort.DtrEnable = true;
_serialPort.RtsEnable = true;
// _serialPort.WriteBufferSize = 1;
_serialPort.Open();
_serialPort.ReadTimeout = 20000;
_serialPort.WriteTimeout = 20000;
}
public void Clear()
{
while (ReadByte() != -1)
continue;
}
private byte[] _array = new byte[] {0};
public void WriteByte(byte value)
{
_array[0] = value;
_serialPort.Write(_array, 0, 1);
// _serialPort.BaseStream.WriteByte(value);
_serialPort.BaseStream.Flush();
}
public void WriteBytes(byte[] array)
{
_serialPort.Write(array, 0, array.Length);
}
private int _readTimeOut = -1;
public int ReadByte(int timeOut = 200)
{
if (timeOut != _readTimeOut)
_serialPort.ReadTimeout = _readTimeOut = timeOut;
try
{
//return _serialPort.BaseStream.ReadByte();
return _serialPort.ReadByte();
// _serialPort.Read(array, 0, 1);
// return array[0];
}
catch (TimeoutException)
{
return -1;
}
}
/// <summary>
/// sends string followed by CR - LF
/// </summary>
/// <param name="line"></param>
public void WriteLine(String line)
{
WriteBytes(StringToBytes(line + "\r\n"));
}
public static byte[] StringToBytes(string input)
{
return Encoding.ASCII.GetBytes(input);
}
public void Close()
{
try
{
_serialPort.Close();
}
catch(IOException)
{
}
}
}
}