首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#端口被拒绝,而线程

C#端口被拒绝,而线程
EN

Stack Overflow用户
提问于 2016-05-07 23:23:37
回答 2查看 305关注 0票数 0

在我的应用程序中使用Microsoft Visual Expres,Win Form应用程序我通过串行通信从PC机向单片机发送数据。它的工作原理是:PC机上的应用程序发送数据-单片机执行其程序-在单片机程序的最后发送字符给应用程序-应用程序接收字符并发送另一个数据。

我的问题是,当我等待微控制器的字符时,整个应用程序(在PC上)变得不活动(无法按任何按钮或关闭程序)。

朋友让我试试Threads。我试着用线程(我在线程方面是个新手)。当我运行我的应用程序时,它抛出了一个异常:访问端口"COM6“被拒绝。看起来串行端口在一个线程中打开了,然后其他线程关闭了该端口。

有没有办法将端口设置为对所有线程开放?或者有更好的主意如何让我的应用程序在等待微控制器响应的同时处于活动状态?

有一些带有线程的代码行:

代码语言:javascript
复制
.
.
.
     poslat(data_all);   //sending data function               
     Thread t = new Thread(cakaj);
     t.Start(); // start of thread cakaj
.
.
.

有发送数据的功能

代码语言:javascript
复制
static void poslat(string data)
{
    SerialPort COMport = new SerialPort();

    COMport.PortName = "COM6"; 
    COMport.BaudRate = 1200;
    COMport.DataBits = 8;
    COMport.Parity = Parity.None;
    COMport.StopBits = StopBits.One;

    COMport.Open();

    COMport.Write(data);
    COMport.WriteTimeout = 500;

    COMport.Close();

}

等待来自微控制器的字符功能

代码语言:javascript
复制
void cakaj()
{
    SerialPort COMport = new SerialPort();
    int byteRead;

    COMport.PortName = "COM6"; // 
    COMport.BaudRate = 1200;
    COMport.DataBits = 8;
    COMport.Parity = Parity.None;
    COMport.StopBits = StopBits.One;

    COMport.Open(); //**Program points there with error message:Acces to the port "COM6" is denied.** 

    do
    { 
        byteRead = COMport.ReadByte();

    } while (byteRead != 75);   // ASCII K = 75
    t.Abort();

   COMport.Close();

    return;
}
EN

回答 2

Stack Overflow用户

发布于 2016-05-07 23:35:02

您正在使用相同的端口COM6创建两个不同的SerialPort COMport实例。您可以做的是将COMport变量作为您的类的字段,并在poslatcakaj中访问它。

此外,您也可以使用DataReceived事件,而不是创建另一个线程。

您的代码将如下所示。

代码语言:javascript
复制
class YourClass
{
    static SerialPort _COMport;
    int byteRead; //make byteRead a field so you can also share it outside cakaj
    SerialPort COMport //share COMport for poslat and cakaj
    {
        get
        {
            if(_COMport == null)
            {
               CreateCOMport();
            }
            return _COMport;
        }
    }

    void CreateCOMport()
    {
        _COMport = new SerialPort();
        _COMport.PortName = "COM6";
        _COMport.BaudRate = 1200;
        _COMport.DataBits = 8;
        _COMport.Parity = Parity.None;
        _COMport.StopBits = StopBits.One;
        _COMport.DataReceived += cakaj;
        //COMport will listen for any incoming data
        //when there is data available, method cakaj will run
    }

    void poslat(string data)
    {
        if (!COMport.IsOpen)
        {
            COMport.Open();
        }
        COMport.Write(data);
        COMport.WriteTimeout = 500;
    }
    void cakaj(object sender, SerialDataReceivedEventArgs e)
    {
        do
        {
            byteRead = COMport.ReadByte();

        } while (byteRead != 75);
        COMport.Close();
    }
}

编辑:记得在这个类中的某个地方调用COMport.Close()。我改变了方法,有很多方法可以改进它,但我认为它会起到作用……

票数 1
EN

Stack Overflow用户

发布于 2016-05-07 23:31:48

如果您希望窗体应用程序的主线程在循环中等待,则必须确保给它提供处理事件的机会。

你可以这样修改你的等待循环:

代码语言:javascript
复制
do
{ 
    Application.DoEvents(); // handle Windows Forms events

    byteRead = COMport.ReadByte();

} while (byteRead != 75);   // ASCII K = 75

这将确保您的应用程序在等待期间仍然可以响应事件。

当然,只有在应用程序的主线程处于等待状态时,才需要这样做。后台线程不需要这样做,事实上,它们不能这样做。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37090273

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档