multithreading problem
-
Ok. I have an app in C#. It uses a com object in main thread. Then there is a button which calls a method in that com object that takes a long time. So I added a thread (backgroundWorker) which calls that function on that COM object. Trouble is that while the worker thread is working the main still is not responsive! Why is that?! Please help!
-
Ok. I have an app in C#. It uses a com object in main thread. Then there is a button which calls a method in that com object that takes a long time. So I added a thread (backgroundWorker) which calls that function on that COM object. Trouble is that while the worker thread is working the main still is not responsive! Why is that?! Please help!
It will be easier for people to help if you post some relevant code snippets. Josh
-
Ok. I have an app in C#. It uses a com object in main thread. Then there is a button which calls a method in that com object that takes a long time. So I added a thread (backgroundWorker) which calls that function on that COM object. Trouble is that while the worker thread is working the main still is not responsive! Why is that?! Please help!
When you refer to your main thread are you meaning that the GUI is unresponsive? If that's the case then you need to use BeginInvoke from your second thread that calls a method on your main thread that updates the GUI. I am not an expert, but I have implimented it serveral times. I still sometimes have to refer to previous code. Check CP for articles on updating your GUI. This is where I found my information. www.lovethosetrains.com
-
Ok. I have an app in C#. It uses a com object in main thread. Then there is a button which calls a method in that com object that takes a long time. So I added a thread (backgroundWorker) which calls that function on that COM object. Trouble is that while the worker thread is working the main still is not responsive! Why is that?! Please help!
Sounds like you need to do a combination of threading and callback when an invoke is required. Here's some of what I did to leave my UI reponsive in my first threaded app while katakana and hiragana flashcards were being displayed to the user. //create a thread and a delegate in my class description private Thread MyCardDisplayThread = null; delegate void MyAllPurposeCallBack(); //start the thread in one of my many methods MyCardDisplayThread = new Thread(new ThreadStart(ShowCharacterList)); MyCardDisplayThread.Start(); //use the delegate to process UI changes //Note: This method is called inside "ShowCharacterList()" method private void ShowHiraganaFlashCard() { if (this.KanaCardPictureBox.InvokeRequired) { //invoke is required so use the delegate to perform the invoke MyAllPurposeCallBack KanaCardDisplay = new MyAllPurposeCallBack(ShowHiraganaFlashCard); this.Invoke(KanaCardDisplay); } else { //invoke is not required or has been achieved and so do what the method //was designed for in the first place this.KanaCardPictureBox.Image = new Bitmap(AppPath+"\\"+HiraganaCards[CurrentKanaIndex]); if (1 == RunningMode) { //this isn't visible during Test mode so only do this in flashcard mode this.RomajiDisplayLabel.Text = null; } } } For every UI manipulation action that you want to perform while you have a process running on another thread, you have to check for InvokeRequired and then use the callback delegate to perform that invoke if it is required, otherwise do what ever that UI manipulation is intended to do. Hope this helps! Mike Poz
-
Sounds like you need to do a combination of threading and callback when an invoke is required. Here's some of what I did to leave my UI reponsive in my first threaded app while katakana and hiragana flashcards were being displayed to the user. //create a thread and a delegate in my class description private Thread MyCardDisplayThread = null; delegate void MyAllPurposeCallBack(); //start the thread in one of my many methods MyCardDisplayThread = new Thread(new ThreadStart(ShowCharacterList)); MyCardDisplayThread.Start(); //use the delegate to process UI changes //Note: This method is called inside "ShowCharacterList()" method private void ShowHiraganaFlashCard() { if (this.KanaCardPictureBox.InvokeRequired) { //invoke is required so use the delegate to perform the invoke MyAllPurposeCallBack KanaCardDisplay = new MyAllPurposeCallBack(ShowHiraganaFlashCard); this.Invoke(KanaCardDisplay); } else { //invoke is not required or has been achieved and so do what the method //was designed for in the first place this.KanaCardPictureBox.Image = new Bitmap(AppPath+"\\"+HiraganaCards[CurrentKanaIndex]); if (1 == RunningMode) { //this isn't visible during Test mode so only do this in flashcard mode this.RomajiDisplayLabel.Text = null; } } } For every UI manipulation action that you want to perform while you have a process running on another thread, you have to check for InvokeRequired and then use the callback delegate to perform that invoke if it is required, otherwise do what ever that UI manipulation is intended to do. Hope this helps! Mike Poz
Wait. So I don't get it. You manipulating the UI from the second thread? But my second thread is sitting in a COM call. How can it do anything else? You lost me :confused:
-
Wait. So I don't get it. You manipulating the UI from the second thread? But my second thread is sitting in a COM call. How can it do anything else? You lost me :confused:
I wrote this as my first line: "Sounds like you need to do a combination of threading and callback when an invoke is required." I wrote that because you didn't supply code examples to give us the full story. Programming doesn't work like "word math" problems. Post your code. Without it we can really only guess what it is that you're actually trying to do and so can only offer possible solutions. Mike Poz
-
I wrote this as my first line: "Sounds like you need to do a combination of threading and callback when an invoke is required." I wrote that because you didn't supply code examples to give us the full story. Programming doesn't work like "word math" problems. Post your code. Without it we can really only guess what it is that you're actually trying to do and so can only offer possible solutions. Mike Poz
So I dropped a backgroundWorker on my main Form, named bgWorker and added two even handlers:
private void OnBtnExecute(object sender, DoWorkEventArgs e) { bgWorker.RunWorkerAsync(); } // this is second thread proc as I understand it and while I'm here main threads UI is not // responsive private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { // oDCRR is the COM object that is created in main thread and in this second thread // does something very long in the ExecuteEx e.Result = oDCRR.ExecuteEx(); } private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // here I process results - this is executed in the main thread again... }
-
So I dropped a backgroundWorker on my main Form, named bgWorker and added two even handlers:
private void OnBtnExecute(object sender, DoWorkEventArgs e) { bgWorker.RunWorkerAsync(); } // this is second thread proc as I understand it and while I'm here main threads UI is not // responsive private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { // oDCRR is the COM object that is created in main thread and in this second thread // does something very long in the ExecuteEx e.Result = oDCRR.ExecuteEx(); } private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // here I process results - this is executed in the main thread again... }
inner wrote:
// oDCRR is the COM object that is created in main thread and in this second thread // does something very long in the ExecuteEx
Okay, so this comment explains the real problem. The main thread is also the UI thread so if you execute a COM process that takes a while to complete, you're litterally blocking the UI thread. I can't guarantee this will work but you need to take the COM operation of the UI/main thread. I would try something like this as this is similar to what I did on my KanaFlash program: //in the class declaration private Thread MyCOMThread = null; private void OnBtnExecute(object sender, DoWorkEventArgs e) { // oDCRR is the COM object that is created in main thread and in this second thread // does something very long in the ExecuteEx MyCOMThread = Thread(new ThreadStart(PerformCOMOperation)); MyCOMThread.Start(); } private void PerformCOMOperation() { e.Result = oDCRR.ExecuteEx(); MyCOMThread.Abort(); ProcessResults(whatever you need here...); } //create a MyCOMThread complete event results processor here private void ProcessResults(some param) { //process results } Hope this helps! Mike Poz