我之前没使用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才行吗?
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才行吗?
解决方法: 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,你自己试试看