VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
楼主: tgy

[分享] 改良的多线程绘图演示程序,供初学多线程者学习(含源码)

  [复制链接]
 楼主| 发表于 2012-2-25 11:40:48 | 显示全部楼层
本帖最后由 tgy 于 2012-2-25 21:34 编辑
sexfio 发表于 2012-2-25 00:26
你这样运行一次是可以,但是看不出问题啊,实际中要大量调用,问题就会出现了
比如我改的这样,你点全部获 ...


经过跟踪调试发现,问题与服务器及网络返回信息有关,可能是当服务器返回信息错误或不能识别或网络超时就会出错,在线程函数中加上on error resume next就可以了,或进一步处理错误.

修改过了的,一直运行都不会崩的,但不要用于网站攻击啊

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

点评

你用createobject创立winhttp 几十个,然后全部异步,不用waitforresponse,直接do..loop判断状态,状态完成的话直接重复下一个数据包,这样搞一天都不会报错,而且不卡,他这个很卡,所以说和winhttp无关  发表于 2012-2-25 18:59
我什么都不知道,说不定winhttp内部就不是线程安全的  发表于 2012-2-25 17:51
acme_pjz 这个问题你怎么看?  发表于 2012-2-25 13:13
是吗?baidu按道理不会返回什么错误吧,我试试  发表于 2012-2-25 12:47
网站攻击肯定用Winsock嘛  发表于 2012-2-25 11:57
回复 支持 反对

使用道具 举报

发表于 2012-2-25 12:53:35 | 显示全部楼层
本帖最后由 sexfio 于 2012-2-25 13:00 编辑
tgy 发表于 2012-2-25 11:40
经过跟踪调试发现,问题与服务器及网络返回信息有关,可能是当服务器返回信息错误或不能识别或网络超时就 ...


晕,啥都没改就加了个纠错???
如果去掉纠错,没几分钟程序就自动消失了,这个肯定不会是百度返回数据的问题啦
这样加个纠错等于掩盖了错误啊,你想想如果我一个线程要从1到30发30个不同的包完成一个任务,经常某个包(还不能确定是哪个包)那里出错直接被纠掉继续或跳转啥的,那我最后怎么处理呢,还一个个判断是到哪步出的错?那不是头大啊,汗,这样不行地


那个出错肯定不是百度返回的问题,不信你可以用 dim x() as winhttp
然后山寨多线程
do
for i = 0 to 20
set x(i) = new winhttp
x(i)。。。  

next

loop
你可以这样不加纠错测试一下,几小时都不会出问题的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-2-25 15:15:44 | 显示全部楼层
本帖最后由 tgy 于 2012-2-25 21:43 编辑
sexfio 发表于 2012-2-25 12:53
晕,啥都没改就加了个纠错???
如果去掉纠错,没几分钟程序就自动消失了,这个肯定不会是百度返回数据的问 ...


没有办法,编程有时必须要对错误进行处理的,还好能抓到错误,on error goto 然后分析处理错误对象,就知道错误出在哪了,我对winhttp不熟,也不感兴趣,自己弄吧
上传下载我一般用winnet API

点评

tgy
我这没有出错过  发表于 2012-2-25 20:49
你这个就算加了纠错一样崩溃,刚测试的,这个问题是比较麻烦啊  发表于 2012-2-25 18:56
回复 支持 反对

使用道具 举报

发表于 2012-3-2 01:13:44 | 显示全部楼层
lz,你应该加个CloseHandle释放线程的堆栈空间啊

点评

tgy
确实没有考虑这个问题,留给大家自己完善去了  发表于 2012-3-2 09:06
回复 支持 反对

使用道具 举报

发表于 2012-3-10 12:16:38 | 显示全部楼层
tgy 发表于 2012-2-25 15:15
没有办法,编程有时必须要对错误进行处理的,还好能抓到错误,on error goto 然后分析处理错误对象,就知道 ...

帮我看下哪错了吧~~~~~~希望能维持住500个以上的线程~~~~

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 2012-3-16 14:44:37 | 显示全部楼层
Public Sub RunThread()
   form1.Show
End Sub

Sub Main()
   CreateThreadByTGY AddressOf RunThread
End Sub

你这个多线程DLL能这样调用吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-3-16 15:48:55 | 显示全部楼层
本帖最后由 tgy 于 2012-3-16 15:52 编辑
sunson 发表于 2012-3-16 14:44
Public Sub RunThread()
   form1.Show
End Sub


请参照例子使用,注意CreateThreadByTGY 函数的原型和参数,还有要处理重复调用Main函数的问题.
在main中启动线程要注意,必须要等到线程创建完成才能退出main过程,不然,线程将不能正常执行,所以最好在main的最后sleep 50(或更大)等待线程创建完成.并且还要注意线程和进程的退出,最好先退出新建的线程后再退出主线程.
最好改成如下:
Declare Function CreateThreadByTGY Lib "VBCreateThread.dll" (Optional ByVal address As Long = 0, Optional ByVal p0 As Long = 0, Optional ByVal p1 As Long = 0, Optional ByVal p2 As Long = 0, Optional ByVal p3 As Long = 0) As Long
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)


Sub Main()
    Static isrun As Boolean
    If isrun Then Exit Sub
    CreateThreadByTGY AddressOf RunThread
    isrun = True
     Sleep 50
End Sub

Sub RunThread(p1 As Long, p2 As Long, p3 As Long, p4 As Long)
   
    Form1.Show
End Sub

点评

我就是想我的程序在处理数据时,会造成程序假死,而一般这种处理放到新线程里面处理,就不会出现假死,所以我想把整个程序都放到线程里面处理,这样应该不会出现在假死  发表于 2012-3-16 17:05
tgy
main过程的第一句加上 App.TaskVisible = True  发表于 2012-3-16 17:05
Public Function GetAppPath() As String GetAppPath = App.Path If Len(GetAppPath) <> 3 Then GetAppPath = GetAppPath & "\" End Function 发现在form_load里用了这个函数,程序就启动不了  发表于 2012-3-16 17:02
tgy
我还没有搞得懂你为什么要从main中启动线程,多线程怕不是这么用的  发表于 2012-3-16 16:57
刚刚搞错了,没有从线程启动,重新试了从线程启动,会出错,根本启动不了,测试程序可以,正式程序不行  发表于 2012-3-16 16:48
回复 支持 反对

使用道具 举报

发表于 2012-3-16 17:07:11 | 显示全部楼层
tgy 发表于 2012-3-16 15:48
请参照例子使用,注意CreateThreadByTGY 函数的原型和参数,还有要处理重复调用Main函数的问题.
在main中 ...

Public Function GetAppPath() As String GetAppPath = App.Path If Len(GetAppPath) <> 3 Then GetAppPath = GetAppPath & "\" End Function
是在form_load事件里面用了这个函数引起程序启动不了,不知道是什么原因不能用这个函数
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-3-16 17:13:30 | 显示全部楼层
本帖最后由 tgy 于 2012-3-16 17:17 编辑

??? ,防止假死未必要使用多线程,且也不是你这种用法,只能将会假死的过程放到新线程中,而不是把窗体的显示放到新线程中.呵呵,还要多了解下多线程及其使用原则,不太熟的话,最好不要用多线程,其实一个doevents 就可以解决你的界面假死问题.
整个程序放到新线程中和放在主线程中没有区别,不会达到你的希望的效果.
回复 支持 反对

使用道具 举报

发表于 2012-3-16 17:17:33 | 显示全部楼层
tgy 发表于 2012-3-16 17:13
??? ,防止假死未必要使用多线程,且也不是你这种用法,只能将会假死的过程放到新线程中,而不是把窗体的显示 ...

肯定不能用doevents,要不能用doevents就好了,其实就是我写的一个http代理程序,用的是winsock控件,接收到数据,要转发到客户端,如果数据量大的话,就会出现假死,winsock接收数据是不能用doevents干扰的,而且我也尝试过用你的多线程DLL直接处理那一段代码,也是会出错
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2022-7-4 19:38

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表