S
Scott Gifford
Hello,
I have a few questions about worker threads interacting with a form.
I'm developing in C# using .NET 2.0 Compact Framework, on the Windows
Mobile platform. I'm using the Visual Studio 2008 beta, but I don't
think any of this question is specific to VS2008.
I know that to interact with a form, the background thread must use
form.Invoke() to call a method in the GUI thread to interact with any
controls. On the compact framework, I cannot send arguments with
Invoke(), so I've been using global variables to communicate this.
For example, if I have a label named "lblStatus", I would create a
corresponding string "newStatus" then write a small method like this:
private void FormUpdateStatus(object sender, EventArgs e)
{
lock (this)
{
if (newStatus != null) {
lblStatus.Text = newStatus;
newStatus = null;
}
}
}
Then from the background thread, I would call a method like this:
public void ThreadUpdateStatus(string s)
{
try
{
lock (this)
{
newStatus = s;
}
this.Invoke(new EventHandler(UpdateStatus));
}
catch (ObjectDisposedException)
{
// Do nothing
}
}
First, I was wondering if this is the best way to approach this, or if
there's a better (or more standard) way to handle this situation,
which must be pretty common?
Second, is it correct and necessary to make all changes to the global
variable inside a locked region, in both the form thread and the
background thread?
Third, I added that "catch (ObjectDisposedException)" because if the
form was closed before the background thread finished, I would get an
exception when the background thread tried to invoke the window. Does
it make sense that I would have to do this every time I use
"control.Invoke" from another thread? Is there a better way to handle
this?
Fourth, can anybody recommend a book/article with more information
about the interaction between background threads and the GUI thread,
and about .NET concurrency in general?
Thanks!
----ScottG.
I have a few questions about worker threads interacting with a form.
I'm developing in C# using .NET 2.0 Compact Framework, on the Windows
Mobile platform. I'm using the Visual Studio 2008 beta, but I don't
think any of this question is specific to VS2008.
I know that to interact with a form, the background thread must use
form.Invoke() to call a method in the GUI thread to interact with any
controls. On the compact framework, I cannot send arguments with
Invoke(), so I've been using global variables to communicate this.
For example, if I have a label named "lblStatus", I would create a
corresponding string "newStatus" then write a small method like this:
private void FormUpdateStatus(object sender, EventArgs e)
{
lock (this)
{
if (newStatus != null) {
lblStatus.Text = newStatus;
newStatus = null;
}
}
}
Then from the background thread, I would call a method like this:
public void ThreadUpdateStatus(string s)
{
try
{
lock (this)
{
newStatus = s;
}
this.Invoke(new EventHandler(UpdateStatus));
}
catch (ObjectDisposedException)
{
// Do nothing
}
}
First, I was wondering if this is the best way to approach this, or if
there's a better (or more standard) way to handle this situation,
which must be pretty common?
Second, is it correct and necessary to make all changes to the global
variable inside a locked region, in both the form thread and the
background thread?
Third, I added that "catch (ObjectDisposedException)" because if the
form was closed before the background thread finished, I would get an
exception when the background thread tried to invoke the window. Does
it make sense that I would have to do this every time I use
"control.Invoke" from another thread? Is there a better way to handle
this?
Fourth, can anybody recommend a book/article with more information
about the interaction between background threads and the GUI thread,
and about .NET concurrency in general?
Thanks!
----ScottG.