各位高手:
   我在VB当中要使用多线程。可是有些问题搞不清楚,代码如下:
ClsMic的代码
Private frmMICCh As FrmMCI
    ' 声 明 定 时 器 容 器 窗 体
Private WithEvents MICCh As MMControl
Private WithEvents Mic As Timer
' 声 明 定 时 器( 包 括 其 事 件)
Public Event JobStart()
' 声 明 任 务 开 始 事 件
Public Event JobEnd()
Private Sub Class_Initialize()
 ' - - - - 类 初 始 化 事 件 - - - -
   Set frmMICCh = FrmMCI
   Set MICCh = FrmMCI.MM
   Set Mic = FrmMCI.Timer1
 End Sub
Private Sub Class_Terminate()
    ' 类 终 止 事 件,释 放 定 时 器 并 卸 载 定 时 器 窗 体
      Set MICCh = Nothing
End Sub
Public Sub StartJob()
    Mic.Enabled = True
    MICCh.Command = "Open"
    MICCh.Command = "Play"
    JobEnd
End Sub
Public Sub JobEnd()
    MICCh.Command = "Close"
End Sub
==================================
Frm1 中的代码:
Private Sub Command1_Click()
    
    Timer1.Enabled = TrueEnd Sub
Private Sub Timer1_Timer()
    Mic.StartJob
End Sub
========================================
类引用窗体代码:
Mic.JobEnd
Set Mic = Nothing
=============================
可是声音老有“断裂”怎么解决?急啊

解决方案 »

  1.   

    一个窗口就是一个线程,其实有时候一个控件也是一个线程 譬如winsock控件
      

  2.   

    MCI设备本身就不会与VB在一个线程中运行,系统会为其创建多个线程用于执行的。
    你在代码中根本没有,也无需再建立线程,Timer是后台执行方式,它不是一个线程!!!
    VB安全性是基于单线程的,VB中使用多线程是有很多风险的,你可参见:
    http://community.csdn.net/Expert/topic/3572/3572458.xml?temp=.8878595
    那里,我有解释。MMControl控件现在很少有人用了,一个API便可搞定!
    最后告诉你:
    Public Sub StartJob()
        Mic.Enabled = True
        MICCh.Command = "Open"
        MICCh.Command = "Play"
        JobEnd
    End Sub
    这段一播放就立即关闭了。不知是什么目的?你要说明自己的想法。
    如果你是想后台放音乐,并实现循环播放,这种代码是徒劳的。
      

  3.   

    回 homezj(小吉) :
      你要将MCI控件引用到VB程序中,他们一定在一个线程当中。我的意思是当我的应用程序在干自己的事情时,当某个条件满足,就让MCI设备自动播放,但是如果这样,当应用程序运行跳出调用时,MCI的播放被迫中断。上面这个代码是有问题。的确,我感到很抱歉。这里有我最新的,请指正:
    ActiveX.EXE代码:======================================================
    Private frmMICCh As FrmWJF
    Private MICCh As MMControlPrivate Sub Class_Initialize()
     ' - - - - 类 初 始 化 事 件 - - - -
       Set frmMICCh = New FrmWJF
       Set MICCh = FrmWJF.MMWJF
     End Sub
    Private Sub Class_Terminate()
          Set MICCh = Nothing
    End SubPublic Sub JobStart()
        MICCh.Command = "Open"
        MICCh.Command = "Play"
    End SubPublic Sub JobEnd()
        MICCh.Command = "Close"
    End Sub
    =======================================================
    调用程序代码:
    Dim Mic As WRJSound
    Dim Michael As WJFSoundPrivate Sub Command1_Click()
            Set Mic = New WRJSound
            Mic.StartJob
    End SubPrivate Sub Command2_Click()
         Set Michael = New WJFSound
         Michael.StartJob
    End Sub
      

  4.   

    vb6.0的多线程比较难,因为控件的问题;建议使用vb.net写多线程。
      

  5.   

    呵呵!你还是理解得不全,MCI控件只是VB与MCI设备通讯的一个中间层,MCI设备是Windows系统提供的一个多媒体硬件无关性的控制总集,它有自己一套完整的控制命令,用于应用程序与其进行对话。你就是将MCI控件引用到VB程序中,并不会也不可能让MCI设备与VB运行在同一个线程中,他一般会为自己创建独立的线程。所以MCI设备运行本身就是并行的,你用不着为其创建多线程并行机制。我想你一定没用过API中的mciSendString,其实MCI控件更像是这个函数的一个外壳,MCI控件自己并不是最终播放设备,它也不过只会向系统发送MCI命令而已。为了防止你误入歧途,临时从我的程序中摘录一个简单示例:我想你够用了。Private Declare Function GetShortPathName Lib "kernel32" Alias "GetShortPathNameA" (ByVal lpszLongPath As String, ByVal lpszShortPath As String, ByVal cchBuffer As Long) As LongPrivate Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As LongPublic glnMusicLen As Long,gstrMyMp3 As String
    'gstrMyMp3="C:\1.mp3" 自己指定音乐名,因没指定设备类型,这里可用所有系统支持有文件类型,Mp3、Wav、Mid、Mpeg等很多,系统会自己识别其具体类型的。Public Function PlayMCI(Cmd As String, Optional ReturnStr As String) As Long
        Dim s As String, i As Long
        s = Space(255)
        PlayMCI = mciSendString(Cmd, s, 255, 0)
        s = RTrim(s)
        ReturnStr = s
    End FunctionPublic Function ShortName(LName As String) As String 'MCI设备有时不能正确识别长文件名,可用这个函数转换
        Dim s As String, i As Long
        i = 255
        s = String(255, Chr(0))
        GetShortPathName LName, s, i
        ShortName = Left$(s, InStr(1, s, Chr(0)) - 1)
    End FunctionPrivate Sub mnuMusic_Click()
       On Error GoTo fail
       Dim i As Long, s As String
       mnuMusic.Checked = Not mnuMusic.Checked
       If mnuMusic.Checked = False Then
          PlayMCI "close Song"
          Timer1 = False
       Else
          PlayMCI "close Song"
          If Dir(gstrMyMp3) <> "" Then
             i = PlayMCI("open """ & ShortName(gstrMyMp3) & """ alias Song")
             If i = 0 Then
                PlayMCI "set Song time format ms"
                PlayMCI "status Song length", s   '显示音乐长度,单位毫秒
                glnMusicLen = val(s) \ 1000
                Label1.Caption = "0:00:00" & "/" & TimeSerial(0, 0, glnMusicLen)
                PlayMCI "Play Song"
                Timer1.Interval=1000
                Timer1 = True         
             End If
          End If
       End If
       Exit Sub
    fail:
       mnuMusic.Checked = False
       Timer1 = False
    End SubPrivate Sub Timer1_Timer()
        Dim i As Long, s As String
        If mnuMusic.Checked Then
            i = PlayMCI("status Song mode", s)  '查询有没有播放状态,看有没有结束
            s = LCase(Left(s, 7))
            If s = "stopped" Or i <> 0 Then
                PlayMCI "close Song"
                PlayMCI "Play Song"            '若放完了,就从头再放(循环)
            Else
                PlayMCI "status Song position", s '查询当前播放到什么位置了
                i = val(s) \ 1000
                Label1.Caption = TimeSerial(0, 0, i) & "/" & TimeSerial(0, 0, glnMusicLen) 
            End If
        Else
            PlayMCI "close Song"
            Timer1.Enabled = False
        End If
    End SubMCI设备命令很多,常用的几个这里我都专门演示了了,很多命令很人性化,就象人说话一样。附注:你这个问题的确与多线程无关,时髦的词虽然好听,但不理解不能乱用!
      

  6.   

    1、升级到vb.net
    2、换用C++
    千万不要用VB作自由线程超级不稳定
      

  7.   

    关于VB多线程的编写,我自己试过N次(N>2000),全部失败,崩溃。自信已经找遍了网络上的所有这方面的代码,结果一样是失败。结果是我放弃了。我现在要学一学。NET,看能不能有所突破。