这个帖子只能100,解决后发另一个帖子给分 我有个框架程序,这个框架程序中有两个线程,一个线程是显示进度,另一个运行业务 流程,之前将业务流程都写在本地程序中;后来为了扩展需要,将他们都分散集成在不 同DLL中,这些DLL都是包含界面的,然后由框架中的PANEL内嵌显示。我的业务流程就是 调用这些DLL的接口函数。 但现在问题来了,程序运行中会出现异常崩溃的情况,并且在DEBUG状态下非常常见,但 每次出现的位置不一样。出现错误后也无法定位,都是弹那个汇编窗口出来了,要么就 是报我的DLL有异常?还有就是"CANVAS DOES NOT ALLOW DRAWING"。 我估计是线程同步的问题, 下面是我的线程代码(非常简单,就是调用主框架中的某个函数) 
__fastcall TMainThread::TMainThread(bool CreateSuspended,int index) 
        : TThread(CreateSuspended) 

        FreeOnTerminate=true; 
        m_index = index; 

//--------------------------------------------------------------------------- 
void __fastcall TMainThread::Execute() 

        //---- Place thread code here ---- 
        //Synchronize(UpdateMainForm); 
        Main->ThreadExecute(m_index); //调用主程序中的流程函数。 
} 我之所以将Synchronize屏蔽了,是因为我发现如果这样调用的话,主框架完全无法响应 用户操作,我之前将代码放在主程序中时也是这样做的,从来没有这样频繁报错。 现在我想问的是,这样写线程到底有没有问题,会是DLL的问题吗?如果必须将代码放在DLL中调用,如何避免出错?

解决方案 »

  1.   

    主框架中的函数就是将DLL接口函数集中调用,当然也包括主框架的显示更新,DLL接口函数调用时,也会对DLL中的界面进行一些更新
      

  2.   

    线程结束的代码怎么写的?Thread.Terminate后面有没有再写代码?因为你有一句FreeOnTerminate=true; 可能会有点问题。
      

  3.   

    MainTest->Terminate();
    MainTest = NULL;就是这了,再没有写代码了
      

  4.   

    凡是在线程中涉及和UI交互的,必须使用Synchronize,否则就很有可能“CANVAS DOES NOT ALLOW DRAWING”,所以Synchronize这里要先保证,然后从其它地方找原因。
      

  5.   

    主程序 和dll 同步比较麻烦。呵呵我也有遇到过。
    在设计程序的时候最好能避免这样的问题的 最好。
    要么  可以尝试用消息控制吧!
      

  6.   

    not interested in C++ Builder
      

  7.   

    异步操作涉及到了UI的操作才会出现CANVAS DOES NOT ALLOW DRAWING
    Synchronize(UpdateMainForm); 
    这个里面执行了什么,贴出来
      

  8.   

    说错了,未进行异步操作就会:CANVAS DOES NOT ALLOW DRAWING 另外把异步操作的代码看下;建议尽量不要在线程中与UI交互,尝试改进使用消息的队列来处理。
      

  9.   

    我线程中的函数就是执行DLL的接口函数,接口函数可能更新DLL自己的界面,也可能会触发主界面的更新
      

  10.   

    更新界面可能的問題在這裏。嘗試通過消息來與UI交互。如果是DLL,為什麼不深度用消息來處理呢。 至少有操作系統來做保障
      

  11.   

    看起来想访问失败了
    你的部分界面在DLL 中,那是不是有些对象没有实例化呢
      

  12.   

    系统运行都还正常,DLL界面显示也正常,工作也正常;但会时不时崩溃
      

  13.   


    你的意思是凡是涉及到界面更新都用消息。
    DLL内部界面更新也用消息处理吗?
      

  14.   

    线程的代码: //--------------------------------------------------------------------------- #include <vcl.h> 
    #pragma hdrstop #include "MainThread.h" 
    #include "MainFrm.h" 
    #pragma package(smart_init) __fastcall TMainThread::TMainThread(bool CreateSuspended) 
            : TThread(CreateSuspended) 

            FreeOnTerminate=true; 

    //--------------------------------------------------------------------------- 
    __fastcall TMainThread::TMainThread(bool CreateSuspended,int index) 
            : TThread(CreateSuspended) 

            FreeOnTerminate=true; 
            m_index = index; 

    //--------------------------------------------------------------------------- 
    void __fastcall TMainThread::UpdateMainForm() 

            Main->ThreadExecute(m_index); 

    //--------------------------------------------------------------------------- 
    void __fastcall TMainThread::Execute() 

            //---- Place thread code here ---- 
            //Synchronize(UpdateMainForm); 
            TCriticalSection * pSection=new TCriticalSection(); 
            pSection->Enter(); 
            Main->ThreadExecute(m_index); 
            pSection->Leave(); 
            delete pSection; 

    //--------------------------------------------------------------------------- 主界面中的ThreadExecute根据不同的index值执行不同的操作 如果要保持这样的结构,如何保证线程间的同步呢? 
      

  15.   

    当一个线程写UI线程中的界面时,Canvas是线程安全的,Canvas资源已被加锁,而另一个线程同时也要访问从而产生"CANVAS DOES NOT ALLOW DRAWING"!
    解决方法一般为采用线程同步的方式保证在一个时刻仅允许单一线程访问UI
      

  16.   

    你这样写,估计是有问题,不过也要看你调用的函数是不是线程安全的。建议使用Synchronize
      

  17.   

    如果运行业务的线程不需要牵涉UI更新,可以对更新进度的线程做一些处理操作UI控件的部分代码转移到中线程当中去执行即可。