Thread execution is freezing the app

daemon

Member
Joined
Jan 18, 2007
Messages
10
Programming Experience
Beginner
Hello guys!
I have an app which is checking an internet page for its content. And my app is checking this page every 2 minutes.
Now, I created a thread to do this...but the problem is that the app is freezing for a second(or a few seconds) when my thread starts running. So I can't move the form..or anything else.
This is my thread:
VB.NET:
[SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] timerMsg_Tick([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Object[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.EventArgs) [/SIZE][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=2] timerMsg.Tick[/SIZE]
[SIZE=2][COLOR=#0000ff]Try[/COLOR][/SIZE]
[SIZE=2]Console.WriteLine([/SIZE][SIZE=2][COLOR=#800000]"Checking for messages..."[/COLOR][/SIZE][SIZE=2] + Now)[/SIZE]
[SIZE=2]thMsg = [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] System.Threading.Thread([/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] System.Threading.ThreadStart([/SIZE][SIZE=2][COLOR=#0000ff]AddressOf[/COLOR][/SIZE][SIZE=2] checkForMessages))[/SIZE]
[SIZE=2]thMsg.Start()[/SIZE]
[SIZE=2][COLOR=#0000ff]Catch[/COLOR][/SIZE][SIZE=2] err [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] Exception[/SIZE]
[SIZE=2]MessageBox.Show([/SIZE][SIZE=2][COLOR=#800000]"timerMsg error: "[/COLOR][/SIZE][SIZE=2] + err.Message)[/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Try[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2][COLOR=#000000] checkForMessages()[/COLOR][/SIZE]
[COLOR=#000000]'code in here[/COLOR]
[SIZE=2][COLOR=#000000][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]
[/COLOR][/SIZE][/COLOR][/SIZE]
Can you tell me please what is the best way to deal with this?
Thank you.
 
Don't use Console class in a winforms application, you could use Debug.Writeline instead.
But this is not causing the delay, there could be something on checkForMessages thread invoking on main thread?
 
This is the code:
VB.NET:
[SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] checkForMessages()[/SIZE]
[SIZE=2][COLOR=#0000ff]Try[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] chimer [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] System.Media.SoundPlayer([/SIZE][SIZE=2][COLOR=#0000ff]My[/COLOR][/SIZE][SIZE=2].Resources.done)[/SIZE]
[SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].InvokeRequired [/SIZE][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].Invoke([/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] MethodInvoker([/SIZE][SIZE=2][COLOR=#0000ff]AddressOf[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].checkForMessages))[/SIZE]
[SIZE=2][COLOR=#0000ff]Else[/COLOR][/SIZE]
[SIZE=2]done = [/SIZE][SIZE=2][COLOR=#0000ff]False[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] ids [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=2] = [/SIZE][SIZE=2][COLOR=#800000]""[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] msgString [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] mes(), pieces() [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][SIZE=2] IO.File.Exists(msgDataPath) = [/SIZE][SIZE=2][COLOR=#0000ff]False[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Or[/COLOR][/SIZE][SIZE=2] IO.File.Exists(msgSchemaPath) = [/SIZE][SIZE=2][COLOR=#0000ff]False[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[SIZE=2]writeMsgXML()[/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[SIZE=2]msgString = getResponse(server, username, password, [/SIZE][SIZE=2][COLOR=#800000]"getMessages"[/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][SIZE=2] Trim(msgString) <> [/SIZE][SIZE=2][COLOR=#800000]""[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[SIZE=2]mes = msgString.Split([/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=2]() {[/SIZE][SIZE=2][COLOR=#800000]"##"[/COLOR][/SIZE][SIZE=2]}, StringSplitOptions.RemoveEmptyEntries)[/SIZE]
[SIZE=2][COLOR=#0000ff]For[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Each[/COLOR][/SIZE][SIZE=2] mySplit [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]In[/COLOR][/SIZE][SIZE=2] mes[/SIZE]
[SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][SIZE=2] Trim(mySplit) <> [/SIZE][SIZE=2][COLOR=#800000]""[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[SIZE=2]pieces = mySplit.Split([/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=2]() {[/SIZE][SIZE=2][COLOR=#800000]"||"[/COLOR][/SIZE][SIZE=2]}, StringSplitOptions.None)[/SIZE]
[SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][SIZE=2] UBound(pieces) >= 4 [/SIZE][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[SIZE=2]msgId = pieces(0)[/SIZE]
[SIZE=2]Console.WriteLine(msgId)[/SIZE]
[SIZE=2]msgSubject = pieces(1)[/SIZE]
[SIZE=2]msgLink = pieces(2)[/SIZE]
[SIZE=2]msgDelay = pieces(3)[/SIZE]
[SIZE=2]addMsgToFile()[/SIZE]
[SIZE=2]x = x + 1[/SIZE]
[SIZE=2]ids = ids & pieces(0) & [/SIZE][SIZE=2][COLOR=#800000]"##"[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Next[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] str [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=2] = MarkAsRead(server, username, password, [/SIZE][SIZE=2][COLOR=#800000]"MarkAsRead"[/COLOR][/SIZE][SIZE=2], ids)[/SIZE]
[SIZE=2]Application.DoEvents()[/SIZE]
[SIZE=2]checkForNewMail()[/SIZE]
[SIZE=2]done = [/SIZE][SIZE=2][COLOR=#0000ff]True[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][SIZE=2] x > 0 [/SIZE][SIZE=2][COLOR=#0000ff]And[/COLOR][/SIZE][SIZE=2] newMail = [/SIZE][SIZE=2][COLOR=#0000ff]True[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[SIZE=2]newMsg = [/SIZE][SIZE=2][COLOR=#0000ff]True[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].TopMost = [/SIZE][SIZE=2][COLOR=#0000ff]True[/COLOR][/SIZE]
[SIZE=2]chimer.Play()[/SIZE]
[SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].SetBitmap(FaceBit1, TransAmount) [/SIZE][SIZE=2][COLOR=#008000]'bitmap for newMail and newMessage[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]ElseIf[/COLOR][/SIZE][SIZE=2] x > 0 [/SIZE][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[SIZE=2]newMsg = [/SIZE][SIZE=2][COLOR=#0000ff]True[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].TopMost = [/SIZE][SIZE=2][COLOR=#0000ff]True[/COLOR][/SIZE]
[SIZE=2]chimer.Play()[/SIZE]
[SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].SetBitmap(FaceBit1, TransAmount) [/SIZE][SIZE=2][COLOR=#008000]'bitmap for newMessage[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]ElseIf[/COLOR][/SIZE][SIZE=2] newMail = [/SIZE][SIZE=2][COLOR=#0000ff]True[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].TopMost = [/SIZE][SIZE=2][COLOR=#0000ff]True[/COLOR][/SIZE]
[SIZE=2]chimer.Play()[/SIZE]
[SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].SetBitmap(FaceBit1, TransAmount) [/SIZE][SIZE=2][COLOR=#008000]'bitmap for newMail[/COLOR][/SIZE]
[SIZE=2]gr.DrawImage([/SIZE][SIZE=2][COLOR=#0000ff]My[/COLOR][/SIZE][SIZE=2].Resources.newMail, [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] System.Drawing.Point(100, 100))[/SIZE]
[SIZE=2][COLOR=#0000ff]Else[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].SetBitmap(FaceBit, TransAmount)[/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Catch[/COLOR][/SIZE][SIZE=2] ex [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] Exception[/SIZE]
[SIZE=2]MessageBox.Show([/SIZE][SIZE=2][COLOR=#800000]"checkForMessagesError: "[/COLOR][/SIZE][SIZE=2] & ex.Message)[/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Try[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]
 
Right. First thing you do here is to check invokerequired on current class instance, which is always true, and then invoke the same method back on the main thread. You are in effect not doing any multi-threading at all. Why is it always true? Because 'Me' keyword is the current class instance from the UI thread you just created a new thread from. That is what 'InvokeRequired' means, "is the control in question being accessed from a different thread".

When you start a new thread only invoke when it is necessary to modify a control created on other (main usually) thread. And when you do so, think again if that is really necessary or if there is a way to avoid it, either by changing that control before starting thread or after it finish, or if it need to be done at all.

Why do you call Application.DoEvents within a worker thread? Don't. Do you know what that call does?

SetBitmap most certainly have something to do with controls on UI thread. Ask yourself, has this part anything to do in the worker thread? or should that be done on UI thread after the worker has finished getting the mails? I would say take it out of there. I don't know what your checkForNewMail method is doing, if it doesn't touch UI it could probably be left, but all code after that call don't belong in a worker thread.

I notice you access several objects/variables in that method that is not declared in that method. Be careful when multithreading and accessing object not created in that thread, consider if you could run into problems with different thread reading/writing the same object at the same time and use locks when needed.

gr.DrawImage in a worker thread where 'gr' is some external graphics instance. Oh my, you got a lot to handle.
 
Back
Top