How to speed up a cross thread call

K

Kueishiong Tu

I have a window form application. I create a worker
thread to make a web request call to retireve data from
the web. When the work is done, I make a marshaled call
to raise an event in the main thread (thanks to William
Ryan, Christine Nguyen, John Saunders, Wiktor Zychla help,
particularly John Saunders). The main thread then
populate the data on a listview on the form. However, I
found the data displaying is very slow compared to the
situation if I wait for the worker thread to finish
through a thread->Join call. Even worse the forecolor and
backcolor are not displayed correctly. What happens here?
Is it becuase the worker thread is still hanging around
so it slows down the main thread? If so, how to get rid
of the worker thread after the cross thread event is
raised?
 
K

Kueishiong Tu

-----Original Message-----
How do you populate the listview?

--tzurs
I simply use the data to create the subitems, and use the
subitems to create the item through a new opeation.
 
J

Jason Smith

Please post a simple example of what you are doing. There could be a lot of
different factors here.
 
K

Kueishiong Tu

-----Original Message-----
Please post a simple example of what you are doing. There could be a lot of
different factors here.

I have resolved the problem. After I change the invoke
call from
tComplete->Invoke(this, EventArgs::Empty);
to
Invoke(tComplete);
Everything works fine. What is the difference between
these calls?

Also if I start the worker thread from a control object,
I couldn't use Invoke(tComplete) call. If I do, I got a
'System.InvalidOperationException'
and the error message is
"The window handle must be established before you can
call Invoke and InvokeAsync". What's going on here?
Following is the complete test program.
----------------------------------------------------------
#pragma once


namespace TestForm4
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Threading;
using namespace System::Diagnostics;

public __gc class Tobj : public Control
{
private: EventHandler *tComplete;

public: Tobj()
{
tComplete = new EventHandler(this, &Tobj::tcomplete);
}

public: __event EventHandler *fcomplete;

/// <summary>
/// This method is called by the
background thread when it has finished
/// the search.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>

private: void tcomplete(System::Object
*sender, System::EventArgs* e)
{
Debug::WriteLine("enter
tcomplete");
fcomplete(sender, e);
}

public: System::Void dothread()
{
Debug::WriteLine(this, "enter
dothread this=");
Thread* tThread = new Thread(new
ThreadStart(this, tThreadProc));
tThread->Start();
}

private: System::Void tThreadProc()
{
// do web request here

// notify the work is complete
//tComplete->Invoke(this,
EventArgs::Empty);

Invoke(tComplete);
}
};

/// <summary>
/// Form1 的摘要
///
/// 警告: 如果您變更這個類別的名稱,就必須變更與這個類別
所依據之所有 .resx 檔案關聯的
/// Managed 資源編譯器工具的 'Resource File Name' 屬
性。
/// 否則,這些設計工具將無法與這個表單關聯的當地語系化資
源正確互動。
/// </summary>
public __gc class Form1 : public
System::Windows::Forms::Form
{
private: Tobj *tobj;
public:
Form1(void)
{
this->tobj = new Tobj();
this->tobj->fcomplete += new
System::EventHandler(this, &Form1::rcomplete);
InitializeComponent();
}

protected:
void Dispose(Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super::Dispose(disposing);
}
private: System::Windows::Forms::Button *
button1;

private:
/// <summary>
/// 設計工具所需的變數。
/// </summary>
System::ComponentModel::Container *
components;

/// <summary>
/// 此為設計工具支援所必須的方法 - 請勿使用程式
碼編輯器修改
/// 這個方法的內容。
/// </summary>
void InitializeComponent(void)
{
this->button1 = new
System::Windows::Forms::Button();
this->SuspendLayout();
//
// button1
//
this->button1->Location =
System::Drawing::point(40, 0);
this->button1->Name = S"button1";
this->button1->TabIndex = 0;
this->button1->Text = S"button1";
this->button1->Click += new
System::EventHandler(this, button1_Click);
//
// Form1
//
this->AutoScaleBaseSize =
System::Drawing::Size(5, 15);
this->ClientSize =
System::Drawing::Size(292, 266);
this->Controls->Add(this-
button1);
this->Name = S"Form1";
this->Text = S"Form1";
this->ResumeLayout(false);

}
private: System::Void button1_Click
(System::Object * sender, System::EventArgs * e)
{
tobj->dothread();
}
private: void rcomplete(System::Object *sender,
System::EventArgs* e)
{
Debug::WriteLine("enter
rcomplete");
};
};
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top