zoukankan      html  css  js  c++  java
  • 托管调试助手 "DisconnectedContext":“上下文 0xf20540 已断开连接... 请确保在应用程序全部完成 RuntimeCallableWrapper (表示其内部的 COM 组件)之前,所有 COM 上下文/单元/线程都保持活动状态并可用于上下文转换

          最近做一个winForm的小工具,用到了 ManagementObjectSearcher/ManagementClass 和 WndProc ,涉及到对 移动设备的检测。

      窗体加载时会执行一个 Reload()方法(通过 ManagementObjectSearcher/ManagementClass 重新获取移动设备盘符),但是当把设备 拔出或插入时,由 WndProc 去执行 Reload() 方法,老是报 :

        托管调试助手 "DisconnectedContext":“上下文 0xf20540 已断开连接。将不会使用代理来处理 COM 组件上的请求。这可能会导致损坏或数据丢失。要避免此问题,请确保在应用程序全部完成 RuntimeCallableWrapper (表示其内部的 COM 组件)之前,所有上下文/单元都保持活动状态。

         怎么来解决这个问题?我也不知道,网上找了很久,没由合适的的解决办法。只有自己分析,去尝试解决了。。

         通过调试,发现  Reload() 在三处有调用,窗体加载,设备插入,设备拔出。窗体加载时,Reload() 没有报错,正常加载,而当设备插入或拔出后,执行Reload() 就会报异常。

         由此可见,可能好像是 不是一个线程 去执行 的  Reload() 导致,窗体加载时是UI线程 主线程 执行,而 插拔 执行的  WndProc 是另外的线程去执行。

         在此,为了保证 Reload() 的 3处地方 执行都是一个线程去执行,怎么实现呢?看代码:

    #region 检测可移动设备
    
            public const int WM_DEVICECHANGE = 0x219;
            public const int DBT_DEVICEARRIVAL = 0x8000;
            public const int DBT_CONFIGCHANGECANCELED = 0x0019;
            public const int DBT_CONFIGCHANGED = 0x0018;
            public const int DBT_CUSTOMEVENT = 0x8006;
            public const int DBT_DEVICEQUERYREMOVE = 0x8001;
            public const int DBT_DEVICEQUERYREMOVEFAILED = 0x8002;
            public const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
            public const int DBT_DEVICEREMOVEPENDING = 0x8003;
            public const int DBT_DEVICETYPESPECIFIC = 0x8005;
            public const int DBT_DEVNODES_CHANGED = 0x0007;
            public const int DBT_QUERYCHANGECONFIG = 0x0017;
            public const int DBT_USERDEFINED = 0xFFFF;
    
            /// <summary>
            /// 检测可移动设备
            /// </summary>
            protected override void WndProc(ref Message m)
            {
                try
                {
                    if (m.Msg == WM_DEVICECHANGE)
                    {
                        switch (m.WParam.ToInt32())
                        {
                            case WM_DEVICECHANGE:
                                break;
                            case DBT_DEVICEARRIVAL://可移动设备 插入   
                                isReload = true;
                                break;
                            case DBT_CONFIGCHANGECANCELED:
                                break;
                            case DBT_CONFIGCHANGED:
                                break;
                            case DBT_CUSTOMEVENT:
                                break;
                            case DBT_DEVICEQUERYREMOVE:
                                break;
                            case DBT_DEVICEQUERYREMOVEFAILED:
                                break;
                            case DBT_DEVICEREMOVECOMPLETE:   //可移动设备 卸载
                                isReload = true;
                                break;
                            case DBT_DEVICEREMOVEPENDING:
                                break;
                            case DBT_DEVICETYPESPECIFIC:
                                break;
                            case DBT_DEVNODES_CHANGED:
                                break;
                            case DBT_QUERYCHANGECONFIG:
                                break;
                            case DBT_USERDEFINED:
                                break;
                            default:
                                break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show((ex.InnerException ?? ex).ToString(), "检测可移动设备时出错", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
    
                base.WndProc(ref m);
            }
    
    
            #endregion
    View Code
            /// <summary>
            /// 因为 Form_Load 与 WndProc 两个不同线程 去调用 ManagementClass 会报异常,故这里 开启一个线程去后台维护更新下拉框。
            /// </summary>
            public Thread thread = null;
            /// <summary>
            /// 是否重新加载 下拉框
            /// </summary>
            public bool isReload = false;
            private void MainForm_Load(object sender, EventArgs e)
            {
                thread = new Thread(Reload);
                thread.IsBackground = true;
                isReload = true;
                thread.Start();
            }
            /// <summary>
            /// 重新加载 移动硬盘盘符
            /// </summary>
            private void Reload()
            {
                while (true)
                {
                    if (!isReload)
                    {
                        Thread.Sleep(500);
                    }
                    else
                    {
                       //这里编写业务逻辑代码。。。。。

             isReload = false; } } }

          注:使用 While True +  Thread.Sleep + 执行标识(isReload)  实现。

  • 相关阅读:
    Python变量常量命名
    代码格式
    Python 输入输出
    数据源
    LaTeX Test
    软件工程
    eclipse-智能提示设置
    java代码里设置指定颜色常值
    命令行中Vim直接打开某行
    Vim里快速替换命令
  • 原文地址:https://www.cnblogs.com/lztkdr/p/DisconnectedContext.html
Copyright © 2011-2022 走看看