473,473 Members | 2,120 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Threading in a form...

Hi,

I'm trying to get my head round Async. procedure calls.

I have the following code:

delegate double GetLabourWIPDelegate(DateTime reqDate);
....
GetLabourWIPDelegate getLabourWIPDelegate = new
GetLabourWIPDelegate(GetLabourWIPOnDate);
AsyncCallback ac = new AsyncCallback(DoResult);
IAsyncResult ar = getLabourWIPDelegate.BeginInvoke(dteToDate.Value,a c,null);
....
private void DoResult(IAsyncResult ar)
{
GetLabourWIPDelegate getLabourWIPDelegate =
(GetLabourWIPDelegate)((AsyncResult)ar).AsyncDeleg ate;
double result = getLabourWIPDelegate.EndInvoke(ar);
lblWIPLabourTo.Text = result.ToString("###,###,###,##0.00");
}

This seems to work, it starts a new thread that async. does the calculation
on the date in dteToDate ( calls GetLabourWIPOnDate), then calls DoResult on
completion which sets the label on the form to the result of the
calculation. Is is correct though?

My other question is, what happens if I want to do another calculation at
the same time. I will be calling the same calculation method, but using a
different date value, and putting the result into a different label. How
would I alter my code to do this?

Hope this makes sense, if not, please ask me to clarify anything.

Thanks,

Chris.
Sep 21 '06 #1
7 1442
Hi Chris,

I usually pass in the delegate reference as the state argument so you can avoid the cast to AsyncResult.

You might want to encapsulate this functionality in a class. You could create a GetLabourWIPAsync method and an event that is
raised when the asynchronous operation has completed. Or, you can create BeginGetLabourWIP and EndGetLabourWIP methods. See the
links below for more info.

In the .NET 2.0 framework you can use a BackgroundWorker component instead of a delegate to provide the same functionality, along
with some extra functionality such as a progress callback and optional cancellation. BackgroundWorker can be used in the designer.

Async design pattern on MSDN:
http://msdn.microsoft.com/library/de...rnoverview.asp

Event-based async pattern on MSDN:
http://msdn2.microsoft.com/en-us/library/wewwczdw.aspx

Best practices for event-based async pattern on MSDN:
http://msdn2.microsoft.com/en-us/library/ms228974.aspx

--
Dave Sexton

"ChrisM" <ch**************@suedeyahoo.comwrote in message news:u1**************@TK2MSFTNGP04.phx.gbl...
Hi,

I'm trying to get my head round Async. procedure calls.

I have the following code:

delegate double GetLabourWIPDelegate(DateTime reqDate);
...
GetLabourWIPDelegate getLabourWIPDelegate = new GetLabourWIPDelegate(GetLabourWIPOnDate);
AsyncCallback ac = new AsyncCallback(DoResult);
IAsyncResult ar = getLabourWIPDelegate.BeginInvoke(dteToDate.Value,a c,null);
...
private void DoResult(IAsyncResult ar)
{
GetLabourWIPDelegate getLabourWIPDelegate = (GetLabourWIPDelegate)((AsyncResult)ar).AsyncDeleg ate;
double result = getLabourWIPDelegate.EndInvoke(ar);
lblWIPLabourTo.Text = result.ToString("###,###,###,##0.00");
}

This seems to work, it starts a new thread that async. does the calculation on the date in dteToDate ( calls GetLabourWIPOnDate),
then calls DoResult on completion which sets the label on the form to the result of the calculation. Is is correct though?

My other question is, what happens if I want to do another calculation at the same time. I will be calling the same calculation
method, but using a different date value, and putting the result into a different label. How would I alter my code to do this?

Hope this makes sense, if not, please ask me to clarify anything.

Thanks,

Chris.

Sep 21 '06 #2
Chris,

First, you cannot access controls from the callback method because it
is running on a thread other than the main UI thread. Forms and
controls must be accessed only from the main UI thread. You'll need to
use the Invoke method to marshal a delegate onto the thread hosting the
label you're wanting to modify.

To execute GetLabourWIPOnDate multiple times simultaneously just keep
calling BeginInvoke on the delegate. If you need to each one to modify
a different label when complete then just pass the label as the state
parameter.

The following example demonstrates how to do this. Hopefully it
compiles...I wrote it without testing.

void ExampleMethod()
{
GetLabourWIPDelegate delegate =
new GetLabourWIPDelegate(GetLabourWIPOnDate);

AsyncCallback callback = new AsyncCallback(DoResult);

delegate.BeginInvoke(date1, callback, label1);
delegate.BeginInvoke(date2, callback, label2);
// ...
delegate.BeginInvoke(dateN, callback, labelN);
}

void DoResult(IAsyncResult ar)
{
Label label = (Label)ar.AsyncState;
if (label.InvokeRequired)
{
// Rerun this method on the UI thread.
Delegate method = new AsyncCallback(DoResult);
object[] parameters = { ar };
label.Invoke(method, parameters);
}
else
{
// We're already on the UI thread!
GetLabourWIPDelegate delegate =
(GetLabourWIPDelegate)((AsyncResult)ar).AsyncDeleg ate;
double result = delegate.EndInvoke(ar);
label.Text = result.ToString("###,###,###,##0.00");
}
}

Brian

ChrisM wrote:
Hi,

I'm trying to get my head round Async. procedure calls.

I have the following code:

delegate double GetLabourWIPDelegate(DateTime reqDate);
...
GetLabourWIPDelegate getLabourWIPDelegate = new
GetLabourWIPDelegate(GetLabourWIPOnDate);
AsyncCallback ac = new AsyncCallback(DoResult);
IAsyncResult ar = getLabourWIPDelegate.BeginInvoke(dteToDate.Value,a c,null);
...
private void DoResult(IAsyncResult ar)
{
GetLabourWIPDelegate getLabourWIPDelegate =
(GetLabourWIPDelegate)((AsyncResult)ar).AsyncDeleg ate;
double result = getLabourWIPDelegate.EndInvoke(ar);
lblWIPLabourTo.Text = result.ToString("###,###,###,##0.00");
}

This seems to work, it starts a new thread that async. does the calculation
on the date in dteToDate ( calls GetLabourWIPOnDate), then calls DoResult on
completion which sets the label on the form to the result of the
calculation. Is is correct though?

My other question is, what happens if I want to do another calculation at
the same time. I will be calling the same calculation method, but using a
different date value, and putting the result into a different label. How
would I alter my code to do this?

Hope this makes sense, if not, please ask me to clarify anything.

Thanks,

Chris.
Sep 21 '06 #3
Brian,

Thank you very much. Exactly what I wanted to know, and some sample code as
well! Usenet answers just don't get much more helpful.
It didn't occur to me that the call back method was being called by the new
thread. Obvious now you've pointed it out, but didn't think at the time. I
can see that programming threads can be somthing of a minefield...

PS.
Only one thing wrong with your code ;-)) you called your Delegate
'delegate' which is obvioulsy a reserved word, and had the compiler whining
a little bit.

PPS

I assume that in calling the 'GetLaboutWIPOnDate' method, each thread gets
its own set of local variables etc, and is 'isolated' from all the other
threads...? I guess the only danger would be if this method referenced (or
rather actually changed) any global values, in which case there would be
some contention?

One more question (sorry!) If the method that is called by the threads,
makes a call to a static method in an object ( eg
MyObject.MyStaticMethod(someValue) ) , is this 'thread safe'? Or will it
cause problems? If it makes a difference, in my case, the static method in
question is a very simple one, it just performs a straightforward
transformation on the value passed in.

Do you have a link to a good introduction to all this stuff that would be
suitable to a newbie thread programmer like myself?

Regards,

Chris.

"Brian Gideon" <br*********@yahoo.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.com...
Chris,

First, you cannot access controls from the callback method because it
is running on a thread other than the main UI thread. Forms and
controls must be accessed only from the main UI thread. You'll need to
use the Invoke method to marshal a delegate onto the thread hosting the
label you're wanting to modify.

To execute GetLabourWIPOnDate multiple times simultaneously just keep
calling BeginInvoke on the delegate. If you need to each one to modify
a different label when complete then just pass the label as the state
parameter.

The following example demonstrates how to do this. Hopefully it
compiles...I wrote it without testing.

void ExampleMethod()
{
GetLabourWIPDelegate delegate =
new GetLabourWIPDelegate(GetLabourWIPOnDate);

AsyncCallback callback = new AsyncCallback(DoResult);

delegate.BeginInvoke(date1, callback, label1);
delegate.BeginInvoke(date2, callback, label2);
// ...
delegate.BeginInvoke(dateN, callback, labelN);
}

void DoResult(IAsyncResult ar)
{
Label label = (Label)ar.AsyncState;
if (label.InvokeRequired)
{
// Rerun this method on the UI thread.
Delegate method = new AsyncCallback(DoResult);
object[] parameters = { ar };
label.Invoke(method, parameters);
}
else
{
// We're already on the UI thread!
GetLabourWIPDelegate delegate =
(GetLabourWIPDelegate)((AsyncResult)ar).AsyncDeleg ate;
double result = delegate.EndInvoke(ar);
label.Text = result.ToString("###,###,###,##0.00");
}
}

Brian

ChrisM wrote:
>Hi,

I'm trying to get my head round Async. procedure calls.

I have the following code:

delegate double GetLabourWIPDelegate(DateTime reqDate);
...
GetLabourWIPDelegate getLabourWIPDelegate = new
GetLabourWIPDelegate(GetLabourWIPOnDate);
AsyncCallback ac = new AsyncCallback(DoResult);
IAsyncResult ar =
getLabourWIPDelegate.BeginInvoke(dteToDate.Value, ac,null);
...
private void DoResult(IAsyncResult ar)
{
GetLabourWIPDelegate getLabourWIPDelegate =
(GetLabourWIPDelegate)((AsyncResult)ar).AsyncDele gate;
double result = getLabourWIPDelegate.EndInvoke(ar);
lblWIPLabourTo.Text = result.ToString("###,###,###,##0.00");
}

This seems to work, it starts a new thread that async. does the
calculation
on the date in dteToDate ( calls GetLabourWIPOnDate), then calls DoResult
on
completion which sets the label on the form to the result of the
calculation. Is is correct though?

My other question is, what happens if I want to do another calculation at
the same time. I will be calling the same calculation method, but using a
different date value, and putting the result into a different label. How
would I alter my code to do this?

Hope this makes sense, if not, please ask me to clarify anything.

Thanks,

Chris.

Sep 22 '06 #4
ChrisM wrote:
Brian,

Thank you very much. Exactly what I wanted to know, and some sample code as
well! Usenet answers just don't get much more helpful.
It didn't occur to me that the call back method was being called by the new
thread. Obvious now you've pointed it out, but didn't think at the time. I
can see that programming threads can be somthing of a minefield...
Well, actually asynchronous delegates run on a thread in the ThreadPool
so if you get a lot of them started then it's likely that at least a
few would be dispatched to the same thread. In other words, if you
kick off 100 of them there won't be 100 new threads created. Just to
stir the pot some more you could run delegates asynchronously using the
ThreadPool.QueueUserWorkItem method as well.

And yes, multithreaded programming is *insanely* difficult. Even
experts get tripped up frequently.
PS.
Only one thing wrong with your code ;-)) you called your Delegate
'delegate' which is obvioulsy a reserved word, and had the compiler whining
a little bit.
Oops :)
PPS

I assume that in calling the 'GetLaboutWIPOnDate' method, each thread gets
its own set of local variables etc, and is 'isolated' from all the other
threads...? I guess the only danger would be if this method referenced (or
rather actually changed) any global values, in which case there would be
some contention?
That is correct. Local variables are allocated on the stack which
means each thread will get its own copy. Like you said, be careful
when accessing class level or instance or static variables. You'll
need to synchronize access to prevent race conditions.
One more question (sorry!) If the method that is called by the threads,
makes a call to a static method in an object ( eg
MyObject.MyStaticMethod(someValue) ) , is this 'thread safe'? Or will it
cause problems? If it makes a difference, in my case, the static method in
question is a very simple one, it just performs a straightforward
transformation on the value passed in.
Since it's only modifying a parameter then yes, it's probably
thread-safe. But, if that parameter reference the same object across
all running instances of the method then it won't be. That didn't
sound like the case though.
Do you have a link to a good introduction to all this stuff that would be
suitable to a newbie thread programmer like myself?
Yes, I do. The following is probably the most cited article.

http://www.yoda.arachsys.com/csharp/threads/

But, this one appears to be well written too.

http://www.albahari.com/threading/
Regards,

Chris.
Sep 22 '06 #5
ChrisM wrote:
Brian,

Thank you very much. Exactly what I wanted to know, and some sample code as
well! Usenet answers just don't get much more helpful.
It didn't occur to me that the call back method was being called by the new
thread. Obvious now you've pointed it out, but didn't think at the time. I
can see that programming threads can be somthing of a minefield...
Well, actually asynchronous delegates run on a thread in the ThreadPool
so if you get a lot of them started then it's likely that at least a
few would be dispatched to the same thread. In other words, if you
kick off 100 of them there won't be 100 new threads created. Just to
stir the pot some more you could run delegates asynchronously using the
ThreadPool.QueueUserWorkItem method as well.

And yes, multithreaded programming is *insanely* difficult. Even
experts get tripped up frequently.
PS.
Only one thing wrong with your code ;-)) you called your Delegate
'delegate' which is obvioulsy a reserved word, and had the compiler whining
a little bit.
Oops :)
PPS

I assume that in calling the 'GetLaboutWIPOnDate' method, each thread gets
its own set of local variables etc, and is 'isolated' from all the other
threads...? I guess the only danger would be if this method referenced (or
rather actually changed) any global values, in which case there would be
some contention?
That is correct. Local variables are allocated on the stack which
means each thread will get its own copy. Like you said, be careful
when accessing class level or instance or static variables. You'll
need to synchronize access to prevent race conditions.
One more question (sorry!) If the method that is called by the threads,
makes a call to a static method in an object ( eg
MyObject.MyStaticMethod(someValue) ) , is this 'thread safe'? Or will it
cause problems? If it makes a difference, in my case, the static method in
question is a very simple one, it just performs a straightforward
transformation on the value passed in.
Since it's only modifying a parameter then yes, it's probably
thread-safe. But, if that parameter reference the same object across
all running instances of the method then it won't be. That didn't
sound like the case though.
Do you have a link to a good introduction to all this stuff that would be
suitable to a newbie thread programmer like myself?
Yes, I do. The following is probably the most cited article.

http://www.yoda.arachsys.com/csharp/threads/

But, this one appears to be well written too.

http://www.albahari.com/threading/
Regards,

Chris.
Sep 22 '06 #6
Hi Dave,

Thanks for your answer, some useful tips and ideas in there!

I'm stuck with .NET 1.1 for now, so can't use any of the new stuff in 2.0
:-(

Cheers,

Chris.

"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:%2***************@TK2MSFTNGP05.phx.gbl...,
Hi Chris,

I usually pass in the delegate reference as the state argument so you can
avoid the cast to AsyncResult.

You might want to encapsulate this functionality in a class. You could
create a GetLabourWIPAsync method and an event that is raised when the
asynchronous operation has completed. Or, you can create
BeginGetLabourWIP and EndGetLabourWIP methods. See the links below for
more info.

In the .NET 2.0 framework you can use a BackgroundWorker component instead
of a delegate to provide the same functionality, along with some extra
functionality such as a progress callback and optional cancellation.
BackgroundWorker can be used in the designer.

Async design pattern on MSDN:
http://msdn.microsoft.com/library/de...rnoverview.asp

Event-based async pattern on MSDN:
http://msdn2.microsoft.com/en-us/library/wewwczdw.aspx

Best practices for event-based async pattern on MSDN:
http://msdn2.microsoft.com/en-us/library/ms228974.aspx
>
--
Dave Sexton

"ChrisM" <ch**************@suedeyahoo.comwrote in message
news:u1**************@TK2MSFTNGP04.phx.gbl...
>Hi,

I'm trying to get my head round Async. procedure calls.

I have the following code:

delegate double GetLabourWIPDelegate(DateTime reqDate);
...
GetLabourWIPDelegate getLabourWIPDelegate = new
GetLabourWIPDelegate(GetLabourWIPOnDate);
AsyncCallback ac = new AsyncCallback(DoResult);
IAsyncResult ar =
getLabourWIPDelegate.BeginInvoke(dteToDate.Value, ac,null);
...
private void DoResult(IAsyncResult ar)
{
GetLabourWIPDelegate getLabourWIPDelegate =
(GetLabourWIPDelegate)((AsyncResult)ar).AsyncDele gate;
double result = getLabourWIPDelegate.EndInvoke(ar);
lblWIPLabourTo.Text = result.ToString("###,###,###,##0.00");
}

This seems to work, it starts a new thread that async. does the
calculation on the date in dteToDate ( calls GetLabourWIPOnDate), then
calls DoResult on completion which sets the label on the form to the
result of the calculation. Is is correct though?

My other question is, what happens if I want to do another calculation at
the same time. I will be calling the same calculation method, but using a
different date value, and putting the result into a different label. How
would I alter my code to do this?

Hope this makes sense, if not, please ask me to clarify anything.

Thanks,

Chris.


Sep 22 '06 #7
Hi Chris,

That's too bad. Just FYI, the async pattern and event-based async pattern info, and the recommendation to encapsulate this
functionality in a business object, is not specific to any version of the framework. Reading those articles will help you to
understand how asynchronous operations actually work in the .NET.

GL

--
Dave Sexton

"ChrisM" <ch**************@suedeyahoo.comwrote in message news:ui**************@TK2MSFTNGP05.phx.gbl...
Hi Dave,

Thanks for your answer, some useful tips and ideas in there!

I'm stuck with .NET 1.1 for now, so can't use any of the new stuff in 2.0
:-(

Cheers,

Chris.

"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message
news:%2***************@TK2MSFTNGP05.phx.gbl...,
Hi Chris,

I usually pass in the delegate reference as the state argument so you can
avoid the cast to AsyncResult.

You might want to encapsulate this functionality in a class. You could
create a GetLabourWIPAsync method and an event that is raised when the
asynchronous operation has completed. Or, you can create
BeginGetLabourWIP and EndGetLabourWIP methods. See the links below for
more info.

In the .NET 2.0 framework you can use a BackgroundWorker component instead
of a delegate to provide the same functionality, along with some extra
functionality such as a progress callback and optional cancellation.
BackgroundWorker can be used in the designer.

Async design pattern on MSDN:
http://msdn.microsoft.com/library/de...rnoverview.asp

Event-based async pattern on MSDN:
http://msdn2.microsoft.com/en-us/library/wewwczdw.aspx

Best practices for event-based async pattern on MSDN:
http://msdn2.microsoft.com/en-us/library/ms228974.aspx

--
Dave Sexton

"ChrisM" <ch**************@suedeyahoo.comwrote in message
news:u1**************@TK2MSFTNGP04.phx.gbl...
Hi,

I'm trying to get my head round Async. procedure calls.

I have the following code:

delegate double GetLabourWIPDelegate(DateTime reqDate);
...
GetLabourWIPDelegate getLabourWIPDelegate = new
GetLabourWIPDelegate(GetLabourWIPOnDate);
AsyncCallback ac = new AsyncCallback(DoResult);
IAsyncResult ar =
getLabourWIPDelegate.BeginInvoke(dteToDate.Value,a c,null);
...
private void DoResult(IAsyncResult ar)
{
GetLabourWIPDelegate getLabourWIPDelegate =
(GetLabourWIPDelegate)((AsyncResult)ar).AsyncDeleg ate;
double result = getLabourWIPDelegate.EndInvoke(ar);
lblWIPLabourTo.Text = result.ToString("###,###,###,##0.00");
}

This seems to work, it starts a new thread that async. does the
calculation on the date in dteToDate ( calls GetLabourWIPOnDate), then
calls DoResult on completion which sets the label on the form to the
result of the calculation. Is is correct though?

My other question is, what happens if I want to do another calculation at
the same time. I will be calling the same calculation method, but using a
different date value, and putting the result into a different label. How
would I alter my code to do this?

Hope this makes sense, if not, please ask me to clarify anything.

Thanks,

Chris.


Sep 22 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Charles A. Lackman | last post by:
Hello and thank you for your assistance. I have attempted to accomplish what I need using delegates with no success. i.e. //Button Click// Dim PollThread As Threading.Thread PollThread = New...
8
by: Z D | last post by:
Hello, I'm having a strange problem that is probably due to my lack of understanding of how threading & COM Interop works in a WinForms.NET application. Here's the situation: I have a 3rd...
6
by: Dan | last post by:
I've created a pocketpc app which has a startup form containing a listview. The form creates an object which in turn creates a System.Threading.Timer. It keeps track of the Timer state using a...
7
by: Anthony Nystrom | last post by:
What is the correct way to stop a thread? abort? sleep? Will it start up again... Just curious... If the thread is enabling a form, if the form is disposed is the thread as well? Thanks, ...
6
by: John Rugo | last post by:
Hi All, I have the most basic understanding of using Threading. I have no problem creating a thread, addressing it to a Sub Procedure, and Starting the Thread. Works Great! My problem is the...
0
by: Colmeister | last post by:
I recently read Jason Clark's excellent article on Unhandled Exceptions (http://msdn.microsoft.com/msdnmag/issues/04/06/NET/default.aspx) and have attempted to incorporate the features he talks...
6
by: hzgt9b | last post by:
Using VS 2003, .NET: I developed a windows application that performs several actions based on an input file. The application displays a progress bar as each action executes. Based on new...
5
by: Miro | last post by:
I will try my best to ask this question correctly. I think in the end the code will make more sence of what I am trying to accomplish. I am just not sure of what to search for on the net. I...
7
by: Mike P | last post by:
I am trying to write my first program using threading..basically I am moving messages from an Outlook inbox and want to show the user where the process is up to without having to wait until it has...
5
by: CCLeasing | last post by:
For an application I'm creating I want to create a 'fake' progress bar. By fake I mean a progress bar that looks like it's doing something but actually isn't. I know philosophically this isn't...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.