VB下,想实现程序各个部分对数据库链接资源使用的独占,VB程序本身没有使用多线程API。参考文档中心的一篇“vb实现多线程 (S.F.)”,使用的是临界区,但是那篇文章提供的用API调用临界区功能的方法,不能执行,一运行就提示内存地址错误,连VB都退出了。而且临界区是需要初始化的,那篇文章中也没有提及,并且临界区API的参数是结构指针。不知道有没有人用API的方法实现成功过。所以,我就想用VC写个组件给VB调用来实现临界区功能。在VC中使用ATL向导,建立的对象,基本代码如下,多余的自动生成代码略去:
class critical_sec : 
{
public:
critical_sec() 
{
InitializeCriticalSection(&crisec);
}
~critical_sec() 
{
DeleteCriticalSection(&crisec);
}
public:
STDMETHOD(leaveSec)();
STDMETHOD(enterSec)();
private:
CRITICAL_SECTION crisec;
};
STDMETHODIMP critical_sec::enterSec()
{
EnterCriticalSection(&crisec);
return S_OK;
}
STDMETHODIMP critical_sec::leaveSec()
{
LeaveCriticalSection(&crisec);
return S_OK;
}
编译成功,并且在VB中也成功使用,没有任何错误。
VB中的程序是,建立一个timer,每2秒向文本框中添加一行当前时间。另有一个按钮,按一下就向文本框中添加一行文字。
引用并建立这个com后,当timer向文本框中添加文字时,先调用enterSec,然后添加文字,然后sleep(用API)1秒,然后才leaveSec。而按钮添加文字时,也是先enterSec,然后添加文字,再leaveSec,没有sleep。
这个timer 中 sleep的时间,希望按钮不能向文本框中添加文字,但实际试验确没有任何效果,用按钮向文本框添加文字不受任何影响。也没有任何错误提示。请问大家,怎么才能给VB实现临界区,或其他对资源的独占功能。

解决方案 »

  1.   

    >>用按钮向文本框添加文字不受任何影响临界区又不能你的操作取消,只是让你等待而已,你将Sleep的时间改为60 * 1000后再试试
      

  2.   

    Private sec As New TBLib.critical_secPrivate Sub Command5_Click()
        sec.enterSec
        Text1.Text = "KKK: " & FormatDateTime(Now(), vbLongTime) & vbCrLf & Text1.Text
        sec.leaveSec
    End SubPrivate Sub Command6_Click()
        If Check1.Value = 0 Then
            Enter
        Else
            Leave
        End If
    End SubPrivate Sub Enter()
        sec.enterSec
        Text1.Text = FormatDateTime(Now(), vbLongTime) & vbCrLf & Text1.Text
        Check1.Value = 1
        DoEvents
    End SubPrivate Sub Leave()
        sec.leaveSec
        Text1.Text = FormatDateTime(Now(), vbLongTime) & vbCrLf & Text1.Text
        Check1.Value = 0
        DoEvents
    End Sub如果临界区起效,则当执行了Enter函数时,就锁定了临界区,而执行Leave函数时释放锁定。但是现在是执行了Enter函数后,Command5_Click的执行依然没有等待。
      

  3.   

    我怀疑是不是VB调用COM为单线程,而临界区函数只是按线程来认定是否所有,因此无论VB里的哪个函数请求进入临界区,都认为是一个线程,而这个线程就永远拥有了这个临界区,不存在互斥。