 |
|
 |
for anyone else having this issue, it's
public class LongProcess
{
#region Members
// Main thread sets this event to stop worker thread:
ManualResetEvent m_EventStop;
// Worker thread sets this event when it is stopped:
ManualResetEvent m_EventStopped;
// Reference to main form used to make syncronous user interface calls:
MainForm m_form;
#endregion
public LongProcess(ManualResetEvent eventStop,
ManualResetEvent eventStopped,
MainForm form)
{
m_EventStop = eventStop;
m_EventStopped = eventStopped;
m_form = form;
}
|
|
|
|
 |
|
|
 |
|
 |
Nicely done. Very helpful.
Short and to the point particularly with follow up comments and considering it was written a while back.
Thanks.
|
|
|
|
 |
|
 |
Dear Sir,
I have a project : build web describe Quck sort, But I dont know to use Thread which will make chart changing visual, please help me
Thanks and best regards,
Openit
|
|
|
|
 |
|
 |
I first thought that your article was answer to my problem:
In your solution, form keeps responsing user interaction while background process executes, but freezes while updating its controls. What I need is, my form should not freeze while updating its controls, which takes a long time. For example, textboxes should allow editing while combo boxes are being filled. I actually am not even sure if it is possible. Have any ideas? Thanks...
asan
"Much that once was is lost for none now live who remember it"
|
|
|
|
 |
|
 |
Try the BackgroundWorker class:
http://msdn2.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
Cheers,
Manuel
|
|
|
|
 |
|
 |
Isn't BackgroundWorker basically the same thing as the code in this article, with additional support for wiring up events rather than manually creating and setting up delegates?
I think that the answer to the problem is that the operations need to be made more granular. That is, if you want to fill a combo box, you should add them one (or a few) at a time rather than filling the entire box.
|
|
|
|
 |
|
 |
I see... maybe you could try creating a queue and then update the controls (dequeue and update) on the Idle event for the application.
You can update a combo an item at a time (don't forget to call CurrencyManager.Refresh() when you want to see the changes).
|
|
|
|
 |
|
 |
Don't you think that the piece of code:
// wait when thread will stop or finish
while (m_WorkerThread.IsAlive)
{
// We cannot use here infinite wait because our thread
// makes syncronous calls to main form, this will cause deadlock.
// Instead of this we wait for event some appropriate time
// (and by the way give time to worker thread) and
// process events. These events may contain Invoke calls.
if ( WaitHandle.WaitAll(
(new ManualResetEvent[] {m_EventThreadStopped}),
100,
true) )
{
break;
}
Application.DoEvents();
}
is a kind of busy waiting? Is there any other way to do it, in a more elegant way?
Regards,
Adam
|
|
|
|
 |
|
 |
More elegant way is using BeginInvoke instead of Invoke in a worker thread. In this case we can use infinite wait without deadlock. If worker thread uses Invoke for some reason (for example, it needs return value of Invoke operation), busy waiting is only way.
|
|
|
|
 |
|
 |
you can use the asyncresult with the begininvoke and endinvoke to get what you need back from the other thread
|
|
|
|
 |
|
 |
Being somewhat new to .NET and C#, I appreciate very much this clearly documented, well written example. I have tried to slog thru many other examples on the web. This one is hands-down the best I've found. It just works great! Thank You! Thank You!
W.
|
|
|
|
 |
|
 |
This example covers almost the whole stuff of thread programming on Windows Forms.
And it doesnt directly result into an unhandled Exception.
You deed a great job.
Thanks
Raymond
|
|
|
|
 |
|
 |
Highly useful article! Perfect example of brevity and knowledge.
DKB
|
|
|
|
 |
|
 |
I've been scouring the web for an example of how to stop a worker thread from the main form and how to tell the main form when an exception is thrown in the worker thread. Your code here is the closest I've seen to something that would work well, but there's one major difference. You're starting the worker thread with Thread.Start, while I'm using Delegate.BeginInvoke.
I need to pass parameters to one of the asynchronus methods, and I need to be able to specify an AsynchCallback method to run when the thread completes. From what I've seen, I can do neither of these things using Thread.Start.
I've looked at the object model, and I can't figure out how to get a handle to the actual thread that I started using BeginInvoke. Is there something that I'm missing? I haven't even been able to stop the thread from the main thread using EndInvoke, and I don't know any other way to even try to stop it.
Thanks.
|
|
|
|
 |
|
 |
Hello ,
i can't create a new control in the function that related with thread
e.g
while(true)
{
...................
.....................
.................
.........
label a=new label();
.....
.
...
....
.
.
.
.
.
}
..
this give an error message at run time and said that you cant create a new control
Thanks
|
|
|
|
 |
|
 |
Add function to the form class which creates new control. Call this function from the worker thread using Invoke or BeginInvoke, by the same way as AddString function is called in the article sample.
|
|
|
|
 |
|
 |
this is the erorr message :
An unhandled exception of type 'System.ArgumentException' occurred in system.windows.forms.dll
Additional information: Controls created on one thread cannot be parented to a control on a different thread.
Thanx
|
|
|
|
 |
|
 |
How u r creating a control on background worker or thread. its impossible.
|
|
|
|
 |
|
 |
hi to all and sorry for my english,
I need to add a control (my custom row) with a separated thread that read the data from database and then create the new row that have to be add in my custom grid(like outlook when receive a new mail).
it's all ok until I invoke the add method in my grid but the system say me the following error:
"The controls created on a thread cannot have like element father a
control on a thread various" (this is a traslate... my .net is italian version).
This is a sample code that simulate my problem.... thanks!!!
Public Class Form1
Inherits System.Windows.Forms.Form
#Region " Codice generato da Progettazione Windows Form "
Public Sub New()
MyBase.New()
'Chiamata richiesta da Progettazione Windows Form.
InitializeComponent()
'Aggiungere le eventuali istruzioni di inizializzazione dopo la chiamata a InitializeComponent()
End Sub
'Form esegue l'override del metodo Dispose per pulire l'elenco dei componenti.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Richiesto da Progettazione Windows Form
Private components As System.ComponentModel.IContainer
'NOTA: la procedura che segue è richiesta da Progettazione Windows Form.
'Può essere modificata in Progettazione Windows Form.
'Non modificarla nell'editor del codice.
Private Sub InitializeComponent()
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(396, 238)
Me.Name = "Form1"
Me.Text = "Form1"
End Sub
#End Region
Private WithEvents Thr As MyThread
Private xThread As System.Threading.Thread
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Thr = New MyThread(Me)
Dim myThreadStart As New System.Threading.ThreadStart(AddressOf Thr.StartThread)
xThread = New System.Threading.Thread(myThreadStart)
xThread.Start()
End Sub
Private Sub Thr_ButtonAdded() Handles Thr.ButtonAdded
MsgBox("new button created!!!")
End Sub
End Class
Public Class MyThread
Public Event ButtonAdded()
Private m_Form As System.Windows.Forms.Form
Sub New(ByVal F As System.Windows.Forms.Form)
m_Form = F
End Sub
Public Sub StartThread()
Beep()
Dim myInvoker As New MethodInvoker(AddressOf NewButton)
myInvoker.Invoke()
End Sub
Private Sub NewButton()
Dim newbtn As New System.Windows.Forms.Button
m_Form.Controls.Add(newbtn)
RaiseEvent ButtonAdded()
End Sub
End Class
|
|
|
|
 |
|
 |
I've just developing my Instant Messaging system using c#,
when the message that shows contacter loggin, I want to refresh my contacter list. Previously, I get a timer to do it instead of using Control.Invoke..
Good example.
Thanks very much.
InteliIM 2004, an .NET Instant Messaging System will be coming soon.
http://plissoft.bigwww.com;P
|
|
|
|
 |
|
 |
Just what I needed. Now I have a worker thread updating my progress bar in the other thread all happily.
Thanks.
Si
|
|
|
|
 |
|
 |
In your article, you have "For tasks like showing database records we need Invoke", could you explain why, and is there any general rule when "Invoke" is preferred over "BeginInvoke"?
Thank you!
|
|
|
|
 |
|
 |
It was written when I just get .NET Beta version. In C++ we cannot post pointer using PostMessage, and database record must be sent synchronously using SendMessage. However, C# handles all these dirty details and any data may be sent synchronously or asynchronously, depending on our needs.
The general rule is that asynchronous call (BeginInvoke) is always preferred over synchronous call (Invoke). The reason for using synchronous call may be, for example, if we need return value of this call and next worker thread operations depend on it.
|
|
|
|
 |
|
 |
This article went a long way to solving a problem I had.
I have a C++ ActiveX control that I can access from a second thread.
Unfortunately, going from Beta 2 to production, I lost my access
(both threads are in the same class).
The problem I found with this solution is that invoke does the work
in my UI thread. This leads to that thread being starved.
It would be nice, if there was a way for me to access the control
directly from the second thread.
Donald A. Zocchi
donzocchi1@attbi.com
donald.a.zocchi@tek.com
|
|
|
|
 |