Thread freezing the application

夙愿已清 提交于 2019-12-25 04:43:15

问题


I'm designing an application which reads DICOM data sets and visualizes them with volume rendering techniques by using VTK library. Anyway, the problem I'm dealing is volume rendering is really CPU-bounded process. If I handle the volume rendering in a single threaded process, application (GUI) freezes and passes to "not responding" state. I have written another thread for volume rendering process. However GUI still freezes, here are the codes.

private: System::Void volumeRenderButton_Click(System::Object^  sender, System::EventArgs^  e) {

             volumeRenderThread = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this, &Form1::volumeRender));
             volumeRenderThread->Priority = System::Threading::ThreadPriority::Lowest;
             volumeRenderThread->Start();                                   
         }

private: void volumeRender()
         {
             threeDPictureBox->Invoke(gcnew volumeDelegate(this, &Form1::volumeDelegateMethod));        

             /*
             if ( threeDPictureBox->InvokeRequired )
             {
                threeDPictureBox->Invoke(gcnew System::Action(this, &Form1::volumeRender));
             }
             else
             {
                 dicom->VolumeRender(threeDPictureBox, vrSettings); 
             }
             */
         }
private: delegate void volumeDelegate();

private: void volumeDelegateMethod()
         {
             dicom->VolumeRender(threeDPictureBox, vrSettings); 
         }


void Dicom::VolumeRender( Windows::Forms::PictureBox ^pictureBox, VRsettings *settings )
{
    renderer = vtkSmartPointer < vtkRenderer > :: New();
    renderWindow = vtkSmartPointer < vtkWin32OpenGLRenderWindow > :: New();
    renderWindow->AddRenderer(renderer);
    renderWindow->SetParentId((HWND)((pictureBox->Handle).ToPointer()));
    renderWindow->SetSize(pictureBox->Width, pictureBox->Height);
    renderWindow->Initialize();
    /* A lot of stuff here */
    ...
    ...
    renderWindow->Render();
    iren->Initialize();     // vtkWin32RenderWindowInteractor

}

threeDPictureBox is a PictureBox component that I'm sending it to volumeRender method of dicom object. vrSettings is a struct for volume Rendering parameters.
When the volume Render button is clicked and click event handler fired, volumeRenderThread starts and freezes the application even I have set its priority Lowest! I have also tried the lines which is commented. None of them works. What's the point I'm missing?? Thanks for answers from now!!


回答1:


You are just passing a delegate that does the actual work back to your UI thread to execute with that call to Invoke so setting the priority of volumeRenderThread doesn't help any.

You need to move as much of the actual work out of the UI thread as possible. Your snip only says /* A lot of stuff here */ so it's hard to suggest exactly how you should go about separating most of the work from the stuff that must be run on the UI thread, but that's what you'll need to do.




回答2:


Your thread is invoked on a method that immediately jumps back onto the UI thread.

In other words, it has one action: tell the UI Thread to do the work.




回答3:


Can you try the following and let me know if it works. My C++ is quite rusty, but the idea is the following. I'm guessing that VTK only needs HWND to do the its job, so you need to retrieve HWND in your UI thread and then pass this to VTK.

Change you code like this (make sure to change my C#isms if any to proper C++):

private: System::Void volumeRenderButton_Click(System::Object^  sender, System::EventArgs^  e) 
{
    volumeRenderThread = gcnew System::Threading::Thread(gcnew System::Threading::ParameterizedThreadStart(this, &Form1::volumeRender));
    volumeRenderThread->Priority = System::Threading::ThreadPriority::Lowest;
    volumeRenderThread->Start(pictureBox->Handle);                                   
}

private: void volumeRender(System::Object^  pictureBox)
{
    dicom->VolumeRender((HWND)((System::IntPtr)pictureBox).ToPointer()), vrSettings); 
}

void Dicom::VolumeRender( HWND pictureBox, VRsettings *settings )
{
    renderer = vtkSmartPointer < vtkRenderer > :: New();
    renderWindow = vtkSmartPointer < vtkWin32OpenGLRenderWindow > :: New();
    renderWindow->AddRenderer(renderer);
    renderWindow->SetParentId(pictureBox);
    renderWindow->SetSize(pictureBox->Width, pictureBox->Height);
    renderWindow->Initialize();
    /* A lot of stuff here */
    ...
    ...
    renderWindow->Render();
    iren->Initialize();     // vtkWin32RenderWindowInteractor
} 


来源:https://stackoverflow.com/questions/6026126/thread-freezing-the-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!