Windows窗体中的多线程问题

时间:2019-02-06 10:06:55

标签: c# c++ .net multithreading winforms

我有一个C ++库,可以实现与硬件的一些通信。由于倾向于与用户交互的主要应用程序是用.Net(使用Windows窗体)编写的,因此我在C ++库周围编写了一个小型包装,并将方法编组为.NET。 C ++包装器是一个简单的单例类,它创建一个实例并允许调用函数:

WRAPPER_API Dev& Wrapper::getInstance()
{
    static Dev instance;
    return instance;
}
WRAPPER_API int iConnect() {
    return Wrapper::getInstance().iConnect();
}
WRAPPER_API int iGetStatus() {
    return Wrapper::getInstance().iGetStatus();
}

因此,创建了WFM,并且连接和第一个状态检索成功(iConnect返回0,iGetStatus返回0)。当我创建一个新线程并将实例传递给它时,问题就开始了(我需要并行线程每2秒检索一次状态信息)。但是,并行线程中iGetStatus的所有调用均返回-1(表示未建立与设备的连接)。
这是我使用的代码:

    namespace DeviceTest
{
    public partial class Form1 : Form
    {
        Dev _api = null;      
        System.Threading.ManualResetEvent _mr = new System.Threading.ManualResetEvent(false);      
        bool _exit = false;
        Thread _pool = null;
        SynchronizationContext _context;

        public Form1(Dev api)
        {
            InitializeComponent();

            System.Drawing.Rectangle workingRectangle = Screen.PrimaryScreen.WorkingArea;

            // Set the size of the form slightly less than size of 
            // working rectangle.
            this.Size = new System.Drawing.Size(800, workingRectangle.Height - 200);
            this.ClientSize = new System.Drawing.Size(this.Size.Width, this.Size.Height);

            this.LogTB.Size = new System.Drawing.Size(this.LogTB.Size.Width, this.Size.Height - this.LogTB.Location.Y - 30);
            this._api = api;

            this.buttonEXIT.Click += (s, e) => this.Close();

            _mr.Reset();
            this._pool = new Thread((o) =>
            {
                _mr.WaitOne();
                int i = 0;
                Dev ap = (Dev)o;
                Thread.Sleep(2000);
                while (!this._exit && (i < 10))
                {
                    var t = ap.iGetStatus();
                    Thread.Sleep(2000);

                    i++;
                }
            });

            this.HandleCreated += (a, b) =>
            {


                this.buttonStartStatusThread.Click += (s, e) =>
                {
                    this._api.iConnect();
                    this._api.iGetStatus();
                    _mr.Set();
                };
            }
    }

有趣的是,如果我在线程中的iGetStatus之前调用iConnect-一切运行良好。
可能会因为同步而错过某些东西吗?


P.S.我已经在C ++和.Net控制台应用程序中使用相同的包装器测试了多线程-一切正常。只有WinForms会出现此问题。

1 个答案:

答案 0 :(得分:0)

看起来这里的主要问题是“线程返回-1(表示未建立与设备的连接)”。您是否将c ++硬件状态检查器作为独立应用程序进行了测试(.Net系统外部)?也许是操作系统特权的问题,应用程序在用户模式下运行,驱动程序(访问硬件)应在内核模式下执行。