468,121 Members | 1,523 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,121 developers. It's quick & easy.

Delegates and Worker Threads, Episode II

Re: Original post = Windows forms - how do I get them to render/update
properly? from August 22.

Okay I am making some progress with being able to use delegates to run
my shelled processes on worker threads. Yes I have gotten it to work,
kind-of - that is I have gotten the shelled processes off of the UI
thread (I think?). But the UI still is not updating properly! Still I
have white boxes for forms, label text that does not update, and extra
windows in the taskbar.

Also I am not sure about the shelled apps themselves - they do not
appear to be multi-threaded because they essentially "take over" the
system - it does not respond at all - for short periods of time.

Anyways something is still preventing the UI in my app from updating
properly. What in the world am I doing wrong here?

Below is some code from the app. I have shortened a lot of stuff to
make it more readable...

....

//part I - declare delegates
public class _SomeClass : System.Windows.Forms.Form
{
private delegate bool _CCDelegate();
private delegate bool _URTDelegate();

[other code below...]

....

//part II - instantiate and invoke

[...other code above]

//check communications
this.lblStatus.Text = "Status: Checking communications, please
wait...";
_CCDelegate CCDelegate = new _CCDelegate(CC);
IAsyncResult CCResult = CCDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(CCDelegate.EndInvoke(CCResult)))
{
this.lblStatus.Text = "Status: Check failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Check was successful.";

//Upload report totals
this.lblStatus.Text = "Status: Uploading report totals, please
wait...";
_URTDelegate URTDelegate = new _URTDelegate(URT);
IAsyncResult URTResult = URTDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(URTDelegate.EndInvoke(URTResult)))
{
this.lblStatus.Text = "Status: Upload of report totals failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Upload of report totals was
successful.";

[other code below...]

....

//part III - functions

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool CC()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool URT()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

....

Okay now I understand that I am using asynchonous processing here, yet
I am blocking with EndInvoke...but I have to make this stuff process
synchonously. It is very important that one process finishes before
the next one begins. If there is a better way then will someone please
post the code?

At this point all I need is:

1. The ability to get processes off of the UI thread so that the UI
continues to update properly.

2. The ability to run those processes syncronously.

I would really appreciate any help from any of you as I really want to
be able to make this work.

Thanks.
Nov 15 '05 #1
12 1872
Joey,

When you say
[...code to launch task on Process class goes here...]
in your delegates, do you mean you are actually launching a process and
perhaps monitoring it, via System.Diagnostics.Process? If so, you can start
a process, set its .ExitCode += new EventHandler(CallbackFuncHere); and then
set its .EnableRaisingEvents = true; Thus you will get a callback when the
process completes (wheter good or bad) from that callback you can chain more
process starts with new callback handlers to "serialize" the whole flow.

My guess is that your delegates take some time to execute. When you do the
following:
IAsyncResult CCResult = CCDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(CCDelegate.EndInvoke(CCResult)))
My theory is that these guys:
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update


all do their magic via a message posted to the main thread. But before you
relinquish program control (to the internal message loop) you hit:
if(!(CCDelegate.EndInvoke(CCResult)))


Which blocks... And viola, its just like you did a plain old invoke!

If you are not using System.Diagnostics.Process to actually create other
processes in the delegates, perhaps you should pass the BeginInvoke a
"callback" delegate. From within this callback you do what amounts to a
non-blocking EndInvoke() and proceed to issue the next BeginInvoke with a
new callback, and so on till everything is serialized to your liking but the
main thread is basically sitting around in its message loop!
Hope this helps.

Regards,
Erin.


Nov 15 '05 #2
Guys, I have read all of the links. I have tried the suggested
options, though I am not sure about the code one would use to
implement either. I have successfully created and used delegates (as
shown in the posted code). However, the UI ***still does not
update***. I have been stuck on this for a few months now. Can anyone
out there offer a simple solution to make this work? Specifically, how
could one modify the posted code to make it update the UI properly? I
am running out of options here...I guess I don't "get it". This
continues to be extremely frustrating, but I am not going to give
up...

Thanks,
JP

"Joe Mayo" <jm***@ddiieessppaammeerrssddiiee.com> wrote in message news:<Og**************@TK2MSFTNGP12.phx.gbl>...
Hi Joey,

Here are some articles on threading that should help you get up to speed.

http://www.windowsforms.net/Default....d=40#Threading

Remember to use Control.Invoke/BeginInvoke, to call a method on your main UI
thread that updates your UI. Also, if you use BeginInvoke, be sure to call
EndInvoke to avoid a memory leak.

Also, check out the asynchronous delegate pattern that uses the
AsyncCallback parameter of BeginInvoke. I may be mistaken, but I think part
of your UI updating problem may be that you are calling EndInvoke in the
same method as BeginInvoke and blocking on your main UI thread. Here's a
reference to the async delegate patterns:

http://msdn.microsoft.com/library/de...rnoverview.asp

Look at the example that says "Supply the callback delegate when beginning
the asynchronous call."

Joe
--
http://www.csharp-station.com
"Joey Powell" <jo*********@goldcoinc.com> wrote in message
news:bd*************************@posting.google.co m...
Re: Original post = Windows forms - how do I get them to render/update
properly? from August 22.

Okay I am making some progress with being able to use delegates to run
my shelled processes on worker threads. Yes I have gotten it to work,
kind-of - that is I have gotten the shelled processes off of the UI
thread (I think?). But the UI still is not updating properly! Still I
have white boxes for forms, label text that does not update, and extra
windows in the taskbar.

Also I am not sure about the shelled apps themselves - they do not
appear to be multi-threaded because they essentially "take over" the
system - it does not respond at all - for short periods of time.

Anyways something is still preventing the UI in my app from updating
properly. What in the world am I doing wrong here?

Below is some code from the app. I have shortened a lot of stuff to
make it more readable...

...

//part I - declare delegates
public class _SomeClass : System.Windows.Forms.Form
{
private delegate bool _CCDelegate();
private delegate bool _URTDelegate();

[other code below...]

...

//part II - instantiate and invoke

[...other code above]

//check communications
this.lblStatus.Text = "Status: Checking communications, please
wait...";
_CCDelegate CCDelegate = new _CCDelegate(CC);
IAsyncResult CCResult = CCDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(CCDelegate.EndInvoke(CCResult)))
{
this.lblStatus.Text = "Status: Check failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Check was successful.";

//Upload report totals
this.lblStatus.Text = "Status: Uploading report totals, please
wait...";
_URTDelegate URTDelegate = new _URTDelegate(URT);
IAsyncResult URTResult = URTDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(URTDelegate.EndInvoke(URTResult)))
{
this.lblStatus.Text = "Status: Upload of report totals failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Upload of report totals was
successful.";

[other code below...]

...

//part III - functions

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool CC()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool URT()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

...

Okay now I understand that I am using asynchonous processing here, yet
I am blocking with EndInvoke...but I have to make this stuff process
synchonously. It is very important that one process finishes before
the next one begins. If there is a better way then will someone please
post the code?

At this point all I need is:

1. The ability to get processes off of the UI thread so that the UI
continues to update properly.

2. The ability to run those processes syncronously.

I would really appreciate any help from any of you as I really want to
be able to make this work.

Thanks.

Nov 15 '05 #3
Can you provide a short and complete prorgram - that compiles - and then
I'll have a look at it (and I'm bet some other people will as well). It's
sometimes hard to piece together exactly what is happenning form small code
fragments (especially when >> is in front of every line).

See Jon Skeet's page on short but complete:
http://www.pobox.com/~skeet/csharp/complete.html

--
Mike Mayer
http://www.mag37.com/csharp/
mi**@mag37.com
"Joey Powell" <jo*********@goldcoinc.com> wrote in message
news:bd**************************@posting.google.c om...
Guys, I have read all of the links. I have tried the suggested
options, though I am not sure about the code one would use to
implement either. I have successfully created and used delegates (as
shown in the posted code). However, the UI ***still does not
update***. I have been stuck on this for a few months now. Can anyone
out there offer a simple solution to make this work? Specifically, how
could one modify the posted code to make it update the UI properly? I
am running out of options here...I guess I don't "get it". This
continues to be extremely frustrating, but I am not going to give
up...

Thanks,
JP

"Joe Mayo" <jm***@ddiieessppaammeerrssddiiee.com> wrote in message

news:<Og**************@TK2MSFTNGP12.phx.gbl>...
Hi Joey,

Here are some articles on threading that should help you get up to speed.
http://www.windowsforms.net/Default....d=40#Threading

Remember to use Control.Invoke/BeginInvoke, to call a method on your main UI thread that updates your UI. Also, if you use BeginInvoke, be sure to call EndInvoke to avoid a memory leak.

Also, check out the asynchronous delegate pattern that uses the
AsyncCallback parameter of BeginInvoke. I may be mistaken, but I think part of your UI updating problem may be that you are calling EndInvoke in the
same method as BeginInvoke and blocking on your main UI thread. Here's a reference to the async delegate patterns:

http://msdn.microsoft.com/library/de...rnoverview.asp
Look at the example that says "Supply the callback delegate when beginning the asynchronous call."

Joe
--
http://www.csharp-station.com
"Joey Powell" <jo*********@goldcoinc.com> wrote in message
news:bd*************************@posting.google.co m...
Re: Original post = Windows forms - how do I get them to render/update
properly? from August 22.

Okay I am making some progress with being able to use delegates to run
my shelled processes on worker threads. Yes I have gotten it to work,
kind-of - that is I have gotten the shelled processes off of the UI
thread (I think?). But the UI still is not updating properly! Still I
have white boxes for forms, label text that does not update, and extra
windows in the taskbar.

Also I am not sure about the shelled apps themselves - they do not
appear to be multi-threaded because they essentially "take over" the
system - it does not respond at all - for short periods of time.

Anyways something is still preventing the UI in my app from updating
properly. What in the world am I doing wrong here?

Below is some code from the app. I have shortened a lot of stuff to
make it more readable...

...

//part I - declare delegates
public class _SomeClass : System.Windows.Forms.Form
{
private delegate bool _CCDelegate();
private delegate bool _URTDelegate();

[other code below...]

...

//part II - instantiate and invoke

[...other code above]

//check communications
this.lblStatus.Text = "Status: Checking communications, please
wait...";
_CCDelegate CCDelegate = new _CCDelegate(CC);
IAsyncResult CCResult = CCDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(CCDelegate.EndInvoke(CCResult)))
{
this.lblStatus.Text = "Status: Check failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Check was successful.";

//Upload report totals
this.lblStatus.Text = "Status: Uploading report totals, please
wait...";
_URTDelegate URTDelegate = new _URTDelegate(URT);
IAsyncResult URTResult = URTDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(URTDelegate.EndInvoke(URTResult)))
{
this.lblStatus.Text = "Status: Upload of report totals failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Upload of report totals was
successful.";

[other code below...]

...

//part III - functions

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool CC()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool URT()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

...

Okay now I understand that I am using asynchonous processing here, yet
I am blocking with EndInvoke...but I have to make this stuff process
synchonously. It is very important that one process finishes before
the next one begins. If there is a better way then will someone please
post the code?

At this point all I need is:

1. The ability to get processes off of the UI thread so that the UI
continues to update properly.

2. The ability to run those processes syncronously.

I would really appreciate any help from any of you as I really want to
be able to make this work.

Thanks.

Nov 15 '05 #4
Sorry, the URL was incorrect. This one is right...

http://www.goldcoinc.com/temp/POST543Report.cs_

"Michael Mayer" <mi**@mag37.com> wrote in message news:<eC**************@tk2msftngp13.phx.gbl>...
Can you provide a short and complete prorgram - that compiles - and then
I'll have a look at it (and I'm bet some other people will as well). It's
sometimes hard to piece together exactly what is happenning form small code
fragments (especially when >> is in front of every line).

See Jon Skeet's page on short but complete:
http://www.pobox.com/~skeet/csharp/complete.html

--
Mike Mayer
http://www.mag37.com/csharp/
mi**@mag37.com
"Joey Powell" <jo*********@goldcoinc.com> wrote in message
news:bd**************************@posting.google.c om...
Guys, I have read all of the links. I have tried the suggested
options, though I am not sure about the code one would use to
implement either. I have successfully created and used delegates (as
shown in the posted code). However, the UI ***still does not
update***. I have been stuck on this for a few months now. Can anyone
out there offer a simple solution to make this work? Specifically, how
could one modify the posted code to make it update the UI properly? I
am running out of options here...I guess I don't "get it". This
continues to be extremely frustrating, but I am not going to give
up...

Thanks,
JP

"Joe Mayo" <jm***@ddiieessppaammeerrssddiiee.com> wrote in message

news:<Og**************@TK2MSFTNGP12.phx.gbl>...
Hi Joey,

Here are some articles on threading that should help you get up to speed.
http://www.windowsforms.net/Default....d=40#Threading

Remember to use Control.Invoke/BeginInvoke, to call a method on your main UI thread that updates your UI. Also, if you use BeginInvoke, be sure to call EndInvoke to avoid a memory leak.

Also, check out the asynchronous delegate pattern that uses the
AsyncCallback parameter of BeginInvoke. I may be mistaken, but I think part of your UI updating problem may be that you are calling EndInvoke in the
same method as BeginInvoke and blocking on your main UI thread. Here's a reference to the async delegate patterns:

http://msdn.microsoft.com/library/de...rnoverview.asp
Look at the example that says "Supply the callback delegate when beginning the asynchronous call."

Joe
--
http://www.csharp-station.com
"Joey Powell" <jo*********@goldcoinc.com> wrote in message
news:bd*************************@posting.google.co m...
> Re: Original post = Windows forms - how do I get them to render/update
> properly? from August 22.
>
> Okay I am making some progress with being able to use delegates to run
> my shelled processes on worker threads. Yes I have gotten it to work,
> kind-of - that is I have gotten the shelled processes off of the UI
> thread (I think?). But the UI still is not updating properly! Still I
> have white boxes for forms, label text that does not update, and extra
> windows in the taskbar.
>
> Also I am not sure about the shelled apps themselves - they do not
> appear to be multi-threaded because they essentially "take over" the
> system - it does not respond at all - for short periods of time.
>
> Anyways something is still preventing the UI in my app from updating
> properly. What in the world am I doing wrong here?
>
> Below is some code from the app. I have shortened a lot of stuff to
> make it more readable...
>
> ...
>
> //part I - declare delegates
> public class _SomeClass : System.Windows.Forms.Form
> {
> private delegate bool _CCDelegate();
> private delegate bool _URTDelegate();
>
> [other code below...]
>
> ...
>
> //part II - instantiate and invoke
>
> [...other code above]
>
> //check communications
> this.lblStatus.Text = "Status: Checking communications, please
> wait...";
> _CCDelegate CCDelegate = new _CCDelegate(CC);
> IAsyncResult CCResult = CCDelegate.BeginInvoke(null, null);
> this.Activate(); //try to force form to update
> this.lblStatus.Refresh(); //try to force form to update
> this.Refresh(); //try to force form to update
> //all or part of form remains white and not updated
> if(!(CCDelegate.EndInvoke(CCResult)))
> {
> this.lblStatus.Text = "Status: Check failed.";
> Environment.Exit(-1);
> }
> this.lblStatus.Text = "Status: Check was successful.";
>
> //Upload report totals
> this.lblStatus.Text = "Status: Uploading report totals, please
> wait...";
> _URTDelegate URTDelegate = new _URTDelegate(URT);
> IAsyncResult URTResult = URTDelegate.BeginInvoke(null, null);
> this.Activate(); //try to force form to update
> this.lblStatus.Refresh(); //try to force form to update
> this.Refresh(); //try to force form to update
> //all or part of form remains white and not updated
> if(!(URTDelegate.EndInvoke(URTResult)))
> {
> this.lblStatus.Text = "Status: Upload of report totals failed.";
> Environment.Exit(-1);
> }
> this.lblStatus.Text = "Status: Upload of report totals was
> successful.";
>
> [other code below...]
>
> ...
>
> //part III - functions
>
> //this entire function should now be on a worker thread, right?
> //this entire function should now be separated from the UI thread,
> right?
> public bool CC()
> {
> try
> {
> bool StatusFlag = false;
>
> [...code to launch task on Process class goes here...]
> //careful to include no interaction with UI
>
> return StatusFlag;
> }
> catch(Exception x)
> {
> MessageBox.Show("FATAL ERROR - " + x.Message);
> bool StatusFlag = false;
> return StatusFlag;
> }
> }
>
> //this entire function should now be on a worker thread, right?
> //this entire function should now be separated from the UI thread,
> right?
> public bool URT()
> {
> try
> {
> bool StatusFlag = false;
>
> [...code to launch task on Process class goes here...]
> //careful to include no interaction with UI
>
> return StatusFlag;
> }
> catch(Exception x)
> {
> MessageBox.Show("FATAL ERROR - " + x.Message);
> bool StatusFlag = false;
> return StatusFlag;
> }
> }
>
> ...
>
> Okay now I understand that I am using asynchonous processing here, yet
> I am blocking with EndInvoke...but I have to make this stuff process
> synchonously. It is very important that one process finishes before
> the next one begins. If there is a better way then will someone please
> post the code?
>
> At this point all I need is:
>
> 1. The ability to get processes off of the UI thread so that the UI
> continues to update properly.
>
> 2. The ability to run those processes syncronously.
>
> I would really appreciate any help from any of you as I really want to
> be able to make this work.
>
> Thanks.

Nov 15 '05 #5
Calling EndInvoke stops the asynchronous processing and blocks until the
function returns. You do not need to call EndInvoke in your class at all. If
you want notification that the process has finsihed, then pass in an
AsyncCallback to the BeginInvoke method. When the process finishes, the
callback you passed in will be called.

If you want to have a progress report at certain intervals then you have a
little more coding to do: it boils down to checking the state of the object
you are processing at a certain interval.

Hope this helps. I will try to reply later with a full example.

Josh
"Joey Powell" <jo*********@goldcoinc.com> wrote in message
news:bd**************************@posting.google.c om...
Guys, I have read all of the links. I have tried the suggested
options, though I am not sure about the code one would use to
implement either. I have successfully created and used delegates (as
shown in the posted code). However, the UI ***still does not
update***. I have been stuck on this for a few months now. Can anyone
out there offer a simple solution to make this work? Specifically, how
could one modify the posted code to make it update the UI properly? I
am running out of options here...I guess I don't "get it". This
continues to be extremely frustrating, but I am not going to give
up...

Thanks,
JP

"Joe Mayo" <jm***@ddiieessppaammeerrssddiiee.com> wrote in message

news:<Og**************@TK2MSFTNGP12.phx.gbl>...
Hi Joey,

Here are some articles on threading that should help you get up to speed.
http://www.windowsforms.net/Default....d=40#Threading

Remember to use Control.Invoke/BeginInvoke, to call a method on your main UI thread that updates your UI. Also, if you use BeginInvoke, be sure to call EndInvoke to avoid a memory leak.

Also, check out the asynchronous delegate pattern that uses the
AsyncCallback parameter of BeginInvoke. I may be mistaken, but I think part of your UI updating problem may be that you are calling EndInvoke in the
same method as BeginInvoke and blocking on your main UI thread. Here's a reference to the async delegate patterns:

http://msdn.microsoft.com/library/de...us/cpguide/htm
l/cpconasynchronousdesignpatternoverview.asp
Look at the example that says "Supply the callback delegate when beginning the asynchronous call."

Joe
--
http://www.csharp-station.com
"Joey Powell" <jo*********@goldcoinc.com> wrote in message
news:bd*************************@posting.google.co m...
Re: Original post = Windows forms - how do I get them to render/update
properly? from August 22.

Okay I am making some progress with being able to use delegates to run
my shelled processes on worker threads. Yes I have gotten it to work,
kind-of - that is I have gotten the shelled processes off of the UI
thread (I think?). But the UI still is not updating properly! Still I
have white boxes for forms, label text that does not update, and extra
windows in the taskbar.

Also I am not sure about the shelled apps themselves - they do not
appear to be multi-threaded because they essentially "take over" the
system - it does not respond at all - for short periods of time.

Anyways something is still preventing the UI in my app from updating
properly. What in the world am I doing wrong here?

Below is some code from the app. I have shortened a lot of stuff to
make it more readable...

...

//part I - declare delegates
public class _SomeClass : System.Windows.Forms.Form
{
private delegate bool _CCDelegate();
private delegate bool _URTDelegate();

[other code below...]

...

//part II - instantiate and invoke

[...other code above]

//check communications
this.lblStatus.Text = "Status: Checking communications, please
wait...";
_CCDelegate CCDelegate = new _CCDelegate(CC);
IAsyncResult CCResult = CCDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(CCDelegate.EndInvoke(CCResult)))
{
this.lblStatus.Text = "Status: Check failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Check was successful.";

//Upload report totals
this.lblStatus.Text = "Status: Uploading report totals, please
wait...";
_URTDelegate URTDelegate = new _URTDelegate(URT);
IAsyncResult URTResult = URTDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(URTDelegate.EndInvoke(URTResult)))
{
this.lblStatus.Text = "Status: Upload of report totals failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Upload of report totals was
successful.";

[other code below...]

...

//part III - functions

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool CC()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool URT()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

...

Okay now I understand that I am using asynchonous processing here, yet
I am blocking with EndInvoke...but I have to make this stuff process
synchonously. It is very important that one process finishes before
the next one begins. If there is a better way then will someone please
post the code?

At this point all I need is:

1. The ability to get processes off of the UI thread so that the UI
continues to update properly.

2. The ability to run those processes syncronously.

I would really appreciate any help from any of you as I really want to
be able to make this work.

Thanks.

Nov 15 '05 #6
Joshua Coady wrote:
Calling EndInvoke stops the asynchronous processing and blocks until
the function returns. You do not need to call EndInvoke in your class
at all. If you want notification that the process has finsihed, then
pass in an AsyncCallback to the BeginInvoke method. When the process
finishes, the callback you passed in will be called.


I think not calling EndInvoke (or any of the other EndXXX methods) is a bad
idea, as this will silently swallow exceptions.

Regards,

Andreas

Nov 15 '05 #7
Joshua Coady wrote:
|| Calling EndInvoke stops the asynchronous processing and blocks until
|| the function returns. You do not need to call EndInvoke in your
|| class at all. If you want notification that the process has
|| finsihed, then pass in an AsyncCallback to the BeginInvoke method.
|| When the process finishes, the callback you passed in will be called.
||
|| If you want to have a progress report at certain intervals then you
|| have a little more coding to do: it boils down to checking the state
|| of the object you are processing at a certain interval.
||
|| Hope this helps. I will try to reply later with a full example.
||
|| Josh
||
||

With *delegates* you are required to pair each BeginInvoke with an EndInvoke, it's only Control.BeginInvoke which doesn't require a
call to EndInvoke.

Willy.

..
Nov 15 '05 #8
Joshua,
You do not need to call EndInvoke in your class at all.


Actually, afaik, you are required to pair each BeginInvoke with an EndInvoke.
--
Abderaware
Fine Components For .NET
Turn on, tune in, download.
zane a@t abderaware.com
Nov 15 '05 #9

"Joshua Coady" <jo**@coady.us> wrote in message
news:eW**************@TK2MSFTNGP11.phx.gbl...
How is that requirement enforced? Or will bad things just happen if I dont? (I'm interested not sarcastic: I'm working on a project that calls
BeginInvoke a lot, but seldomly calls EndInvoke.)
It isn't enforced and that's part of the problem. There are many classes
that use the EndInvoke as the equivalent of a call to Dispose, and they use
this call to cleanup. If you don't call EndInvoke then you may get memory
leaks, files not getting closed, transport connections not cleaned up, etc.

Control.Invoke is an exception to this - the .net team at this point has
made assiurances that it is safe to not call EndInvoke on a control.

For example, see the code I posted to this thread. I call begin on the
delegate but not end and it compiles and runs as expected.

I've included the text of that post below so you dont have to go find it.

Josh

-------------------------

Nov 15 '05 #10
Joshua Coady wrote:
|| How is that requirement enforced? Or will bad things just happen if
|| I dont? (I'm interested not sarcastic: I'm working on a project that
|| calls BeginInvoke a lot, but seldomly calls EndInvoke.)
||
|| For example, see the code I posted to this thread. I call begin on
|| the delegate but not end and it compiles and runs as expected.
||
|| I've included the text of that post below so you dont have to go
|| find it.
||
|| Josh
||

No it's not enforced, but it's kind of "documented" (see: Asynchronous programming overview - CAUTION Always call EndInvoke after
your asynchronous call completes.)

The main reasons why you should pair a successful BeginInvoke (or Beginxxx in general) with its EndInvoke (Endxxx) counterpart are:

1. Exceptions thrown by the asynch. method have no immediate effect, the exception object is passed to the caller at the point of
calling EndInvoke. So when your asynch. method running on a threadpool thread can possibly throw an exception you need to call
EndInvoke in order to catch.
2. The BeginInvokemethod is no managed method, it is a CLR on the fly synthesized internal using some precious native resources to
do it's job. Calling EndInvoke will release this stuff, while failing to call EndInvoke will delay this clean-up until GC and
Finalizer run.
3. Some FCL API's misbehave when Endxxx is not called after a successful call of Beginxxx (fi. BeginRead on a stream).

Willy.


Nov 15 '05 #11
To make the code I posted conform to this, all you have to do is add the endinvoke to the DoneAdding method. This may involve checking to see if it has completed yet, but that is clearly shown in the MSDN examples.

Would everyone agree that this would make the code a complete example?

Josh

In article <eU**************@tk2msftngp13.phx.gbl>, wi*************@pandora.be says...
Joshua Coady wrote:
|| How is that requirement enforced? Or will bad things just happen if
|| I dont? (I'm interested not sarcastic: I'm working on a project that
|| calls BeginInvoke a lot, but seldomly calls EndInvoke.)
||
|| For example, see the code I posted to this thread. I call begin on
|| the delegate but not end and it compiles and runs as expected.
||
|| I've included the text of that post below so you dont have to go
|| find it.
||
|| Josh
||

No it's not enforced, but it's kind of "documented" (see: Asynchronous programming overview - CAUTION Always call EndInvoke after
your asynchronous call completes.)

The main reasons why you should pair a successful BeginInvoke (or Beginxxx in general) with its EndInvoke (Endxxx) counterpart are:

1. Exceptions thrown by the asynch. method have no immediate effect, the exception object is passed to the caller at the point of
calling EndInvoke. So when your asynch. method running on a threadpool thread can possibly throw an exception you need to call
EndInvoke in order to catch.
2. The BeginInvokemethod is no managed method, it is a CLR on the fly synthesized internal using some precious native resources to
do it's job. Calling EndInvoke will release this stuff, while failing to call EndInvoke will delay this clean-up until GC and
Finalizer run.
3. Some FCL API's misbehave when Endxxx is not called after a successful call of Beginxxx (fi. BeginRead on a stream).

Willy.

Nov 15 '05 #12

"Joshua Coady" <jo**@coady.us> wrote in message news:MP************************@msnews.microsoft.c om...
To make the code I posted conform to this, all you have to do is add the endinvoke to the DoneAdding method. This may involve checking to see if it has completed yet, but that is clearly shown in the MSDN examples.
Would everyone agree that this would make the code a complete example?

Josh


I do agree..

Willy.

Nov 15 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Steve Lutz | last post: by
1 post views Thread by Natalia DeBow | last post: by
12 posts views Thread by Grant | last post: by
3 posts views Thread by Oscar Thornell | last post: by
1 post views Thread by Howard Weiss | last post: by
14 posts views Thread by Lior Amar | last post: by
18 posts views Thread by didacticone | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.