为什么VB 使用多线程时,在IDE中没任何问题,但编译成EXE文件时就出现错误?

解决方案 »

  1.   

    有些人说还是用 ActiveX 到底什么意思不明白`?
      

  2.   

    在使用本机代码进行编译时,我发现有时候会引入一些莫名其妙的错误。在编译环境中我的代码完全正确地被执行了,但是用本机代码选项生成的EXE文件却不能正确执行。通常这种情况是......参考 
    http://www.chinaaspx.com/article/vb.net/342.htm
      

  3.   

    但是VB6纯API多线程程序只能以P代码编译,不能以本机代码编译
    而且在新线程中,访问主线程的对象(如控件、ADO对象等)必须手动做列集处理
    那是顶级COM高手才能玩得转的
      

  4.   

    还有一点就是,我在网络上经常看到,大家说使用 ActiveX 代替线程?
    我试过,ActiveX 似乎并不会自动创建新的线程啊?
      

  5.   

    //列集处理是指什么?我在线程回调函数中确实有访问主线程对象。列集是指,为了将COM对象传递到另一环境(另一线程、另一进程、局域网上的另一台机器),必须对其作一些封装处理一般跨线程列集是调用CoMarshalInterThreadInterfaceInStream,相当复杂想学VB6多线程,去看Matthew Curland写的《Advanced Visual Basic》此书书评:
    http://dev.csdn.net/develop/article/13/13308.shtm
      

  6.   

    //还有一点就是,我在网络上经常看到,大家说使用 ActiveX 代替线程?那是指再写一个ActiveX Exe来做费时操作
    核心思想是用多进程来实现并行运行
      

  7.   

    Ted Pattison对Matthew Curland中《Advanced Visual Basic》手动列集实现多线程的看法:Ted Pattison著,王新昌等译,《COM+ 与 Visual Basic 6 分布式应用程序设计》(Programming Distributed Applications with COM+ and Microsoft Visual Basic Second Edition)。机械工业出版社,2001.6
    第七章 在COM+应用中共享资源(Chapter 7 Sharing Resources in a COM+ Application)
    7.1 共享线程(Sharing Threads)
    7.1.2 COM的线程管理模型(COM's Threading Models)译本 P144
    -- 机械工业出版社译本 -----------一定不要从Visual Basic中调用CreateThread  如果不对CoInitialize或CoInitializeEx进行显示COM库调用,一个Win32线程就不能参与COM编程。这些函数将线程与单元相关联。对于线程来说,在调用这些函数之前参与任何COM相关活动都是非法而且通常是致命的。幸运的是,COM+运行时在生成一个线程时为你进行这种调用。如果正在创建一个标准EXE或ActiveX EXE项目,Visual Basic运行时在后台进行所需要的CoInitialize调用。
      直接使用Win32线程和COM单元是困难的,而且就应用目的来说,这也超过Visual Basic编程语言的能力。但是,当Visual Basic 5第一次发行时,许多程序员试图通过使用Visual Basic的AddressOf这一操作,在Win32API中直接调用CreateThread函数。这些程序员发现它们能成功调用CreateThread,但是它们的应用程序经常奇怪而神秘的终止。
      调用CreateThread所存在的问题是,它生成了一个新的对COM或单元一无所知的Win32线程。因此使用这样一个线程在COM对象上调用方法是非法的。这讲导致相当严重问题,因为所有的Visual Basic对象,包括窗体和控件,都是COM对象。这样的对象只能由运行在该对象单元的线程访问。当新生成的线程试图改变某个文本框的值时,应用就会崩溃。这是不要直接从Visual Basic代码中使用CreateThread的一个极好的理由。
      一个具有COM线程模型只是的Visual Basic程序员可能试图使问题更进一步。可以通过直接调用像CoInitialize这样的函数来关联一个线程与STA。但是,一当你把一个线程与一个单元关联,复杂性就增加了。例如,你需要编写代码从一个单元到另一个单元传递接口引用(实际上在这一层次传递的是接口指针)。如果你在一个COM方法调用中传递接口引用,代理和占位将自动创建。然而使用其它技术来传递,需求将戏剧性地增加。必须对类型库的两个复杂调用--对CoMarshalInterface的调用将在对象单元中创建一个占位,对CoUnmarshalInterface的调用将在调用者单元中创建一个代理。而且,还必须对COM有足够的了解以确定这些调用何时是必要的。加上与COM+规则和环境相关的复杂性,你应该得出一个重要的结论:一定不要从Visual Basic中调用CreateThread。如果真的需要声称自己的线程,你应该使用C++,而且了解大量有关COM底层管件(plumbing)的知识。
      我必须承认这里的讨论仅仅代表了这样的一种观点。Visual Basic世界的一些偶像,如Matthcw Curland,提倡使用上面叙述的方式直接从Visual Basic代码生成线程。在它所写的一本名为《Advanced Visual Basic 6: Power Techniques for Everyday Programs》(由Addison Wesley出版社)的书Matthcw会告诉你这项工作的细节。
      如果你对我在第三章里所设计的所有COM细节感到熟悉,并且你正在寻找更深入的探讨,Matthcw的书可以带你走向另一个层次。Matthcw已经对Visual Basic开发小组进行了相当多年的跟踪研究,它具有有关Visual Basic运行是如何与COM库交互的内幕知识。他叙述了许多技术,包括在Visual Basic代码中直接从COM库中调用。
    -- 英文原文 ----------------------Never Call CreateThread from Visual Basic A Win32 thread can't participate in COM programming without making an explicit COM library call to either CoInitialize or CoInitializeEx. These functions associate a thread with an apartment. It's illegal and usually fatal for a thread to participate in any COM-related activities before calling one of these functions. Fortunately, the COM+ runtime makes this call for you when it creates a thread. If you're creating a Standard EXE or an ActiveX EXE, the Visual Basic runtime makes all of the required calls to CoInitialize behind the scenes.Working directly with Win32 threads and COM apartments is difficult and, for all practical purposes, beyond the capabilities of the Visual Basic programming language. However, when Visual Basic 5 first shipped, many unfortunate programmers tried to directly call the CreateThread function in the Win32 API by using Visual Basic's new AddressOf operator. The programmers found that they could successfully call CreateThread but that their applications often died strange and mysterious deaths.The problem with calling CreateThread is that it creates a new Win32 thread that knows nothing about COM or apartments. It's therefore illegal to use this thread to invoke a method on a COM object. This creates quite a problem because all Visual Basic objects, including forms and controls, are also COM objects. Such an object can be directly accessed only by the thread running in the object's apartment. When the newly created thread tries to change a value in a text box, the application crashes. This is a pretty good reason to never use CreateThread directly from Visual Basic code.A determined Visual Basic programmer with knowledge of COM's threading models might try to take things to the next level. You can associate a thread with an STA by calling a function such as CoInitialize directly. However, once you associate the thread with an apartment, the complexity increases. For instance, you're typically required to write code for marshaling interface references (which are really interface pointers at this level) from one apartment to another. If you pass the interface references in a COM method call, the proxy and the stub are created automatically. However, if you pass them using another technique, the requirements increase dramatically. You must make two complicated calls to the COM library-a call to CoMarshalInterface to create a stub in the object's apartment and a call to CoUnmarshalInterface to create a proxy in the caller's apartment. What's more, you also have to know enough about COM to decide when these calls are necessary. Add in the complexities related to the rules of COM+ and contexts, and you should come to an important conclusion: Never call CreateThread from Visual Basic. If you really need to spawn your own threads, you should be using C++ and you should know a great deal about the underlying plumbing of COM.I must admit that this entire sidebar is just an opinion. Some of the icons of the Visual Basic world, such as Matt Curland, advocate spawning threads directly from Visual Basic code in the manner I just described. Matt can tell you about the details of this undertaking in a book he's written titled Advanced Visual Basic 6: Power Techniques for Everyday Programs (published by Addison Wesley).If you feel comfortable with all the COM details I covered in Chapter? and you're looking for more in-depth coverage, Matt's book can take you to the next level. Matt has worked on the Visual Basic team for quite a few years and he has intimate knowledge of how the Visual Basic runtime interacts with the COM library. He describes many techniques that involve calling into the COM library directly from Visual Basic code.
      

  8.   

    我使用线程的主要目的在于网络编程时,心条探测用的。因为当主线程出现模式对话框,比如文件对话框,以及Msgbox类的。主线程的其他工作都会被暂停,连Timer都会被暂停。有没有办法其他办法解决这个问题?当弹出对话框时让Timer继续工作`
      

  9.   

    Timer会暂停那是VB的Bug
    编译成exe后Timer就不会暂停了
    网络编程?WinSock控件?
    当WinSock控件收到数据的时候,不是会触发DataArrival事件吗
      

  10.   

    永远不要尝试用VB去写多线程,这样只会浪费时间可以考虑用C或者用 ActiveX Exe的方案
      

  11.   

    //还有一点就是,我在网络上经常看到,大家说使用 ActiveX 代替线程?小弟不才,有一个ActiveX EXE的例子......http://www.m5home.com/bbs/dispbbs.asp?boardID=10&ID=556&page=1不过这也是参照网上的一些文章写的.另外,对于那个"每个对象使用一个线程"的编译选项,还不太明白.......那样的话,在那个ActiveX EXE里不就是多线程了吗?郁闷......
      

  12.   

    ActiveX EXE是多进程 不是多线程 呵呵
    想耍多线程就别耍VB
      

  13.   

    两年前我曾用VB写过一个多线程的WinSock程序,运行还算可以。在编写过程中发现不要调用COM对象,程序就能运行。缺点是所有消息和控制全部用API,且共享内存访问时要用隔离区和指针两种进行访问,决不能直接访问。