找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 13058|回复: 12

[求助] 关于那个单元线程有点不明白的

 火.. [复制链接]

1

主题

11

回帖

0

精华

初来乍到

积分
13
发表于 2010-10-7 09:44:00 | 显示全部楼层 |阅读模式
首先感谢紫水晶给我们带来这么详细的教程。小女感激不尽。
但是有几点不太明白。
1、我看到多线程的实例都是用的activex exe。请问用activex dll行不行呢?我试了一下,用activex dll的话,弹出一个msgbox,主窗体上的计时器不会停止,但无法操作主窗体。而activex exe的话都不会限制。
2、如果用activex dll。我在实例化对象的时候采用数组的形式:
Dim WithEvents ss As Class1
    ReDim ss(5)
    For i = 0 To 5
       Set ss(i) = New Class1
       ss(i).GetHtml
    Next i
这样不执行。而 Dim WithEvents ss() As Class1 这种声明方式又不可以。
怎样才能动态创建多个实例?
3、是不是只能用createobject的方式才算是创建多个单元线程?用set xxx=new class1  不算?

谢谢大家!

1

主题

11

回帖

0

精华

初来乍到

积分
13
 楼主| 发表于 2010-10-7 09:49:06 | 显示全部楼层
小女是想用inet获取网页源码。

1

主题

11

回帖

0

精华

初来乍到

积分
13
 楼主| 发表于 2010-10-7 10:21:06 | 显示全部楼层
用 Dim ss() As actexe
然后
redim ss(10)
    For i = 0 To 5
        Set ss(i) = New actexe
    Next i
倒是可以。但是不能触发事件了。因为没带withevents

275

主题

3019

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17066

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2010-10-7 11:20:56 | 显示全部楼层
感谢关注本论坛

1、我看到多线程的实例都是用的activex exe。请问用activex dll行不行呢?
    我曾经测试过ActiveX DLL,结果是无法创建新的单元线程,即使线程模型里选中了"单元线程".因此只能使用ActiveX EXE.

2、怎样才能动态创建多个(带事件)实例?
    这个问题的解决办法是,将带事件的对象在一个类模块里声明,然后把声明为这个类模块类型的数组进行实例化.

3、是不是只能用createobject的方式才算是创建多个单元线程?用set xxx=new class1  不算?
    是的.引用一下MSDN原文的解释:
内部对象和外部对象的创建
如果客户端请求一个可在外部创建的类的实例,Visual Basic 将在线程池的下一个线程上创建该对象,或者在一个新的线程上创建。不过,如果这个对象接着又请求一个可在外部创建的类的实例,那么,以后发生的情况将取决于第二个实例是如何创建的:

    如果使用 New 操作符创建新的对象,或是使用声明为 As New 的变量,那么该兄弟对象将不会在另一个线程上创建。该对象将共享创建它的对象的线程(以及全局数据),如从属对象那样。

    如果新的对象是用 CreateObject 函数创建,那么它就象客户端请求该对象一样。Visual Basic 将根据线程指定的模型,选择在线程池的下一个线程还是在一个新线程上创建该对象。
我就是嗷嗷叫的老马了......

1

主题

11

回帖

0

精华

初来乍到

积分
13
 楼主| 发表于 2010-10-7 11:30:38 | 显示全部楼层
贴一下代码:
activex里的代码:

类模块部分:
Dim WithEvents frm As Form1
Public Event ok()
Private Sub Class_Initialize()
    Set frm = New Form1
   
End Sub

Private Sub Class_Terminate()
    Set frm = Nothing
End Sub

Private Sub frm_GetOver()
    MsgBox "thread_GetOver"   '这个不显示??
    RaiseEvent ok
End Sub

Public Sub begin()
    frm.Inet1.Execute "www.baidu.com"
End Sub

窗体部分:
Public Event GetOver()

Private Sub Inet1_StateChanged(ByVal State As Integer)
    If State = 12 Then
        RaiseEvent GetOver
        MsgBox "inet1"        '这个可以显示出来。
    End If
End Sub

调用工程:


Dim WithEvents ss As actexe

Private Sub Command2_Click()

'第1种方式,完全正常:
    Set ss = New actexe
    ss.begin

'第2种方式,不触发那个事件,就是我说无论如何不显示的地方,但是那个inet事件中有显示
'    ReDim ss(1)
'    Set ss(0) = New actexe
'    Set ss(1) = New actexe
'第3种方式和第2种方式一样的效果
'    ss(0).begin
'    ss(1).begin
'    For i = 0 To 1
'        Set ss(i) = CreateObject("actexe22.actexe")
'或者用这种方式        Set ss(i) = New actexe
'        ss(i).begin
'    Next i
End Sub

Private Sub ss_ok()
    MsgBox "ok"
End Sub


后面的2种创建对象的方式,都不能显示那个
Private Sub frm_GetOver()
    MsgBox "thread_GetOver"   '这个不显示??
    RaiseEvent ok
End Sub
而inet_statechanged里却证明已经是状态12了。

也就是说,怎么动态创建一个带事件的对象呢?我的这个方法怎么会不触发事件。55555

1

主题

11

回帖

0

精华

初来乍到

积分
13
 楼主| 发表于 2010-10-7 11:47:20 | 显示全部楼层
感谢关注本论坛

1、我看到多线程的实例都是用的activex exe。请问用activex dll行不行呢?
    我曾经 ...
马大哈 发表于 2010-10-7 11:20


谢谢老马指教。
这样可以触发事件了。
不过,因为在窗体上定义那个类的实例,也是不带事件的。所以无法在这个类中触发事件让窗体去处理以后的工作了?

1

主题

11

回帖

0

精华

初来乍到

积分
13
 楼主| 发表于 2010-10-7 11:51:59 | 显示全部楼层
如果使用 New 操作符创建新的对象,或是使用声明为 As New 的变量,那么该兄弟对象将不会在另一个线程上创建。该对象将共享创建它的对象的线程(以及全局数据),如从属对象那样。

奇怪了,我就是用的 Set aa = New actexe
但是看那个activex exe 的进程的线程数,确实是增加了。
比如我创建6个实例,线程数是15,我创建2个实例,线程数是11

275

主题

3019

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17066

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2010-10-7 17:32:27 | 显示全部楼层
谢谢老马指教。
这样可以触发事件了。
不过,因为在窗体上定义那个类的实例,也是不带事件的。所以无 ...
tingyan 发表于 2010-10-7 11:47


线程间通讯的过程比较复杂,也容易出问题,我给你一个我曾经用过的流程:

线程分为UI线程1个与工作线程N个.

工作线程内部的事件产生后,先由本线程内部的一个缓冲池保存,然后使用PostMessage发送自定义消息,通知UI线程"有事件产生".

UI线程通过子类化收到这个自定义消息,然后才联系工作线程,取回数据.

具体到实现,就是那个包装对象中有一个取数据的方法,由窗体接收到通知后调用这个方法取到数据,与事件的效果是相同的.

   
奇怪了,我就是用的 Set aa = New actexe
但是看那个activex exe 的进程的线程数,确实是增加了。
比如 ...
tingyan 发表于 2010-10-7 11:51


这个就有些奇怪了,我这里的测试结果与MSDN中所说的情况是一致的,使用New关键字并不能增加线程.

也许有别的地方有差异.

如果可以,请上传一个测试工程,我测试一下看看.

1

主题

11

回帖

0

精华

初来乍到

积分
13
 楼主| 发表于 2010-10-7 18:56:49 | 显示全部楼层
谢谢老马抽时间指点。
您说的对我来说有点悬乎。呵呵。
我现在又不想放在窗体中处理数据了。呵呵
我放在主程序的类模块中去处理。但是:
在主程序中的类模块里处理数据,发现如果线程太多(我弄了100个线程,不停地inet.execute,完成一次就继续),当我点击窗口上的关闭时,会将主程序挂起,因为数据处理在主程序里。所以感觉在主程序中处理数据这个思路不好。
我现在改到线程中那个类模块中处理数据了。这样测试好像是不会挂起主程序。。。记不清了。我这个程序测试上百次了。都弄晕了。
如果线程多,好像应该把尽量多的工作放在线程里。否则主程序仍然还要处理大量数据,和循环差不多了。。所以会卡,是不是这样?

还有就是,这种方法,是不是类似多个exe在独立工作,他们之间不会有数据混乱吧。嘻嘻,比较笨哦,:loveliness:刚接触这个。

1

主题

26

回帖

0

精华

银牌会员

积分
329
发表于 2010-10-7 19:22:15 | 显示全部楼层
如果另外创建exe能及时进行数据交互也不错啊

275

主题

3019

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17066

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2010-10-7 20:32:50 | 显示全部楼层
如果另外创建exe能及时进行数据交互也不错啊
zzhgb 发表于 2010-10-7 19:22



    进程间通讯,参考这个帖子:

http://www.m5home.com/bbs/thread-4073-1-1.html

275

主题

3019

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17066

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2010-10-7 20:34:49 | 显示全部楼层
回复 9# tingyan


    实际上你的要求就是UI不挂起.

这样的话,使用Inet控件的异步模式不就OK了么.....还可以直接使用数组控件.

只不过你要做好数据处理的问题.

如果处理数据时占用太多时间,界面也会挂起.

1

主题

13

回帖

0

精华

铜牌会员

积分
146
发表于 2011-1-17 07:58:03 | 显示全部楼层
activex dll也是可以的,只不过不用事件返回,直接用定时器检测处理结果就行了.
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表