我之前没使用c#的,用MFC编制了一个小程序,是带多线程,有显式客户端的应用程序,后来想迁移到c#,就编译成了dll。但是在c#中检测dll中的线程结束时,在dll入口函数中使用了一个指示变量,通过一个定时器来检测那个变量是否置零来判断是否已经结束,在mfc下面完全通过。但是在c#中先用了system.window.forms下面的timer,不行,后来换了system.threading.timer,检测是检测出来了,就是在检测出来的位置,本来弹出一次的messagebox竟然弹出了很多次才结束。阅读了msdn下面的timer参考,还是想不透。出问题的代码如下://……………………省略
        private void 数据摘录ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (bOpenProject == false)
            {
                MessageBox.Show("没有指定项目文件,请先新建项目文件或选择已有的项目之后再尝试。");
                return;
            }
            //显式调用dll进行计算            数据摘录ToolStripMenuItem.Enabled = false;            hModule = LoadLibrary("VSFloodExtract.dll");
            if (hModule == IntPtr.Zero)
            {
                throw new Exception("加载动态链接库 VSFloodExtract.dll 失败,请检查是否执行程序目录或系统目录下是否存在该文件。");
            }
            IntPtr ptr = GetProcAddress(hModule, "Show");
            FuncEntrance FuncCalc = (FuncEntrance)Marshal.GetDelegateForFunctionPointer(ptr, typeof(FuncEntrance));            nThreadUseCount ++;  ------------用来检测的一个指针变量            bExitFlag = false;              timer_Delegate = new TimerCallback(DetectDllCanRelease);
            timer_detectdll = new System.Threading.Timer(timer_Delegate,this,Timeout.Infinite, 500);            FuncCalc(strProjectFileName, ref nThreadUseCount);            timer_detectdll.Change(1000, 500);
        }        private void DetectDllCanRelease(Object stateInfo)
        {
            //timer_DetectDll.Stop();            if(nThreadUseCount == 0 && bExitFlag == false)
            {
                //可以释放dll资源
                bExitFlag = true;
                FreeLibrary(hModule);
                MessageBox.Show("调用dll处理完毕。");
                数据摘录ToolStripMenuItem.Enabled = false;                timer_detectdll.Change(Timeout.Infinite, Timeout.Infinite);
                timer_detectdll.Dispose();
            }            return;
        }
//……………………究竟是什么回事,请大家帮忙分析分析。难道要使用剩下的一种system.timer才行吗?

解决方案 »

  1.   

    我以前也遇到过你这种情况,主要原因是在显示对话框的时候你必须要点击确定,但是就在这段Interval=100;的时间里,在这100ms的时间里你没有点击确定所以他一直在弹出对话框。
    解决方法: if(nThreadUseCount == 0 && bExitFlag == false) 
                { 
                    //可以释放dll资源 
                    bExitFlag = true; 
                    FreeLibrary(hModule); 
                    timer_detectdll.Change(Timeout.Infinite, Timeout.Infinite); 
                    timer_detectdll.Dispose(); 

                    MessageBox.Show("调用dll处理完毕。");                 数据摘录ToolStripMenuItem.Enabled = false;                             } 
    先让timer控件停止,再显示对话框,这样就会只有一个对话框显示出来了。
    不知道我以前遇到的麻烦是否和你一样。我没有给你调试,我这台电脑上没装VS,你自己试试看
      

  2.   

    ShowDialog是模式窗体,强制获取焦点,并且线程会中断,等待窗体关闭后才会继续执行后续操作!Show是非模式的,Show完以后继续执行代码,所以就一直Show个不停
      

  3.   

    多谢楼上的支持!后来我用了工作者线程方式解决了这个问题。发现用timer正如二楼所说,是在你没有参与点击的情况下在后台不断弹出新的窗口,但是系统没有及时销毁弹出窗口。