未处理C#COM端口
这是我第一次在这里互动!我正在自学C#除了我试图消除的bug之外,还会有很多错误,请耐心点:) 我正在开发一个非常基本的应用程序,可以让你与串口进行交互,类似于Arduino中集成的工具。 有一个用于连接/断开连接的按钮,它启动/停止后台工作人员,使表单不断更新新数据。我试着移动。关闭();代码中的每一个地方,但都没有改变,当我再次尝试打开它时,它捕获到异常。其他应用程序也无法访问。我想我根本不知道自己在做什么:) 你能帮我释放资源吗 此操作涉及的代码:未处理C#COM端口,c#,com,serial-port,dispose,C#,Com,Serial Port,Dispose,这是我第一次在这里互动!我正在自学C#除了我试图消除的bug之外,还会有很多错误,请耐心点:) 我正在开发一个非常基本的应用程序,可以让你与串口进行交互,类似于Arduino中集成的工具。 有一个用于连接/断开连接的按钮,它启动/停止后台工作人员,使表单不断更新新数据。我试着移动。关闭();代码中的每一个地方,但都没有改变,当我再次尝试打开它时,它捕获到异常。其他应用程序也无法访问。我想我根本不知道自己在做什么:) 你能帮我释放资源吗 此操作涉及的代码: private void Connec
private void ConnectB_Click(object sender, EventArgs e)
{
if (!connected)
{
int baud = Convert.ToInt32(baudRate.SelectedItem.ToString());
COMport = new SerialPort(COMpick.SelectedItem.ToString(), baud, Parity.None, 8, StopBits.One);
try
{
COMport.Open();
connected = true;
ConnectB.Text = "Disconnect";
}
catch (ArgumentOutOfRangeException)
{
MessageBox.Show("Baud rate not valid.");
connected = false;
}
catch (ArgumentException)
{
MessageBox.Show("Port name not valid.");
connected = false;
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("Access denied, try close applications that may using the port.");
connected = false;
}
if (backWorker.IsBusy != true)
{
backWorker.RunWorkerAsync();
}
}
else
{
connected = false;
backWorker.CancelAsync();
ConnectB.Text = "Connect";
}
}
private void backWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
while (true)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else if(COMport.IsOpen)
{
// Get data and print it in the form
try
{
inbox = COMport.ReadLine() + '\n';
}
catch (InvalidOperationException) { }
//Scroll down the form, passing something useless to make it work
worker.ReportProgress(inbox.Length);
}
}
}
private void backWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.COMport.Close();
this.COMport.Dispose();
}
谢谢大家! 使用Debug+Windows+Threads调试器窗口对此进行调试。您应该看到调用CancelAsync()没有任何效果,您的BGW被卡在ReadLine()调用中,因此不会检查CancellationPending,因此永远不会完成。在单击事件处理程序中调用Close()以将其取消锁定。或者使用DataReceived事件处理程序,这样就根本不需要BGW。使用BackgroundWorker的另一种替代方法是使用
SerialPort.BaseStream
对象,使用async/Wait模式调用Stream.ReadAsync()
方法。这三种选择中的任何一种都应该很好;请注意,所有这些都涉及从GUI关闭SerialPort
对象,您知道对Close()
的调用将实际执行。:)@HansPassant使用数据接收事件是一个很好的主意,但是如果接收到连续的流,恐怕GUI会冻结!明天我会再次回家,尝试你的解决方案。但是无论如何,为什么不发布一个答案而不是评论呢?@PeterDuniho我将研究整个异步/等待的过程work@HansPassant我删除了BGW并添加了Datareceived事件。Microsoft给出的示例工作正常(),但在我的表单应用程序中,事件根本不会触发!