0% found this document useful (0 votes)
8 views

Safe, Simple Multithreading in Windows Forms, Part 3

Uploaded by

manthanb
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Safe, Simple Multithreading in Windows Forms, Part 3

Uploaded by

manthanb
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

Safe, Simple Multithreading in Windows Forms, Part 3 (Wonders of Wi... http://msdn.microsoft.com/library/en-us/dnforms/html/winforms0123200...

! "

& &7
! % 08
#
$ # % & 5 # &

' % ()* (++) 6 # &

# % # % ,- # 9 # &
. # * # # % !
// & "

# 0 +/()(++) 1 0

- 0 . 2 2 . & # 0 #
#% 0 & *- 0 0 3 0 * # # -3 2 . & # 2 # 0 - .
% - . . % # - 4 # - # *-0 % # - #
# 0 ! % # &* # # % ,- #
. # * # # % !

5 0 0 * % # & ! *6 ( # # % 0 % &
% 0 & . # * &% # # 0 & 0% % % 0 # . #
# ,- # 7

void ShowProgress(..., out bool cancel) {


if( _pi.InvokeRequired == false ) { ... }
// Transfer control to UI thread
else {
ShowProgressDelegate showProgress =
new ShowProgressDelegate(ShowProgress);

// Avoid boxing and losing our return value


object inoutCancel = false;

// Show progress synchronously (so we can check for cancel)


Invoke(showProgress, new object[] { ..., inoutCancel});
cancel = (bool)inoutCancel;
}
}

5 # % & % % .0 # ,- # * & 0 # # # %
# # $ % # % % 0 0 * #
% % & 1 # ,- # & # 0 # .
# # 0 # 1 * # % & 1 0 & % & $ &
# # * % % % . # 0 &7

1 de 6 02-12-2005 18:36
Safe, Simple Multithreading in Windows Forms, Part 3 (Wonders of Wi... http://msdn.microsoft.com/library/en-us/dnforms/html/winforms0123200...

void ShowProgress(..., out bool cancel) {


// Make sure we're on the right thread
if( this.InvokeRequired == false ) {...}
// Transfer control to correct thread
else {
ShowProgressDelegate
showProgress = new ShowProgressDelegate(ShowProgress);

// Show progress synchronously (so we can check for cancel)


Invoke(showProgress, new object[] {...});

// Check for Cancel the easy, but special-purpose, way


cancel = (state == CalcState.Canceled);
}
}

! % * # . * # % . 4% 0 # . # 0 #
0 * # %&# % % % 0 " * 3 #
# # % % & :% . # . 0 % % * %
# . 0 & # # # & "* # # 3 #
& % & # ; . <" - 3 % # 0 % # 0
# 0 # & # -0 # 1 & # & :% # - . % %
00* - 0 & # & % # 0 # ! .7

class ShowProgressArgs : EventArgs {


public string Pi;
public int TotalDigits;
public int DigitsSoFar;
public bool Cancel;

public ShowProgressArgs(
string pi, int totalDigits, int digitsSoFar) {
this.Pi = pi;
this.TotalDigits = totalDigits;
this.DigitsSoFar = digitsSoFar;
}
}

delegate void ShowProgressHandler(object sender, ShowProgressArgs e);

# # " # 0 # #$ " # &% *


& # . # % &% 4 # # * # &
# . 7

void ShowProgress(...) {
// Make sure we're on the right thread
if( this.InvokeRequired == false ) {...}
}
// Transfer control to correct thread
else {
ShowProgressHandler
showProgress =
new ShowProgressHandler(AsynchCalcPiForm_ShowProgress);
object sender = System.Threading.Thread.CurrentThread;
ShowProgressArgs
e = new ShowProgressArgs(pi, totalDigits, digitsSoFar);
Invoke(showProgress, new object[] {sender, e});
cancel = e.Cancel;
}
}

void AsynchCalcPiForm_ShowProgress(object sender, ShowProgressArgs e) {


ShowProgress(e.Pi, e.TotalDigits, e.DigitsSoFar, out e.Cancel);
}

# 3 # & & % * # * % # . #
0 # " 4 # &% # ,- # # %&#
# # . . # # * % & #$ " 9 4 - % %
# # & * . & % # &% 0 # " 4 0 % $ &
% # . # * % % # 0 & # % % 1 & % # "
0 * # %&# 0 # . # 0 # ,-
# * # 3 & 0 % # . # 3 # ,- # . & # #
0 & &

# % & % 0% # 0 0 # 0% 0 " 0*
& # 0 # 7

2 de 6 02-12-2005 18:36
Safe, Simple Multithreading in Windows Forms, Part 3 (Wonders of Wi... http://msdn.microsoft.com/library/en-us/dnforms/html/winforms0123200...

void ShowProgress(object sender, ShowProgressArgs e) {


// Make sure we're on the right thread
if( this.InvokeRequired == false ) {
piTextBox.Text = e.Pi;
piProgressBar.Maximum = e.TotalDigits;
piProgressBar.Value = e.DigitsSoFar;

// Check for Cancel


e.Cancel = (state == CalcState.Canceled);

// Check for completion


if( e.Cancel || (e.DigitsSoFar == e.TotalDigits) ) {
state = CalcState.Pending;
calcButton.Text = "Calc";
calcButton.Enabled = true;

}
}
// Transfer control to correct thread
else {
ShowProgressHandler
showProgress =
new ShowProgressHandler(ShowProgress);
Invoke(showProgress, new object[] { sender, e});
}
}

void CalcPi(int digits) {


StringBuilder pi = new StringBuilder("3", digits + 2);
object sender = System.Threading.Thread.CurrentThread;
ShowProgressArgs e = new ShowProgressArgs(pi.ToString(), digits, 0);

// Show progress (ignoring Cancel so soon)


ShowProgress(sender, e);

if( digits > 0 ) {


pi.Append(".");

for( int i = 0; i < digits; i += 9 ) {


int nineDigits = NineDigitsOfPi.StartingAt(i+1);
int digitCount = Math.Min(digits - i, 9);
string ds = string.Format("{0:D9}", nineDigits);
pi.Append(ds.Substring(0, digitCount));

// Show progress (checking for Cancel)


e.Pi = pi.ToString();
e.DigitsSoFar = i + digitCount;
ShowProgress(sender, e);
if( e.Cancel ) break;
}
}
}

# # :% # * 0 * & 9 % -3 % 3
# # . & & * & # ,-* # # . & # & 0 1 0
% & # ,- # 3 & 0 # & -3 0 % # # 0 # & # * &
# # . # * & # ,- # * # % & # . # # % %
# # -3 & 9 % % 0 # . ,- # %
0 0 &* # 0 # " & & #
% # % % & % ,- . & #

" ' $
= 0 # # 3 % ! # %
. & & # 1 # # & # % &
* % # 6 > - & ! .9 # % & 0 % &
9 *0 % & 7

public class CalcPiService : System.Web.Services.WebService {


[WebMethod]
public string CalcPi(int digits) {
StringBuilder pi = new StringBuilder("3", digits + 2);

// Way cool fast pi calculator running on a huge processor...

return pi.ToString();
}
}

& 0 # & # % # 0 % 9 & # %


& # # #%& * # & 0 # # %
" # %&# # % & 0 69 > 9 * % 0

3 de 6 02-12-2005 18:36
Safe, Simple Multithreading in Windows Forms, Part 3 (Wonders of Wi... http://msdn.microsoft.com/library/en-us/dnforms/html/winforms0123200...

:% 0 .0 # & 0 3 0 * 3 % # 9 1
& % ? % % @ # ( % # # " ') # % " '
$ & % # ,5 0 # &% & " # #
3 . A# 7BB # B 6 B 6 1< 0 1 - #
% 4 0 # 7BB # B 6 B 6 1< * 3 . #
% 1 % # C % BC6 4 B
5 0 BC B5 0 B5 0 # & 1 0 # . .
# 7

namespace AsynchCalcPi.localhost {
[WebServiceBindingAttribute(Name="CalcPiServiceSoap", ...)]
public class CalcPiService : SoapHttpClientProtocol {
public CalcPiService() {
this.Url =
"http://localhost/CalcPiWebService/CalcPiService.asmx";
}

[SoapDocumentMethodAttribute("http://tempuri.org/CalcPi", ...)]
public string CalcPi(int digits) {...}

public IAsyncResult
BeginCalcPi(
int digits,
System.AsyncCallback callback,
object asyncState) {...}

public string EndCalcPi(IAsyncResult asyncResult) {...}


}
}

& # 0 & 0 # 1 & # # 3 7

localhost.CalcPiService service = new localhost.CalcPiService();

void calcButton_Click(object sender, System.EventArgs e) {


piTextBox.Text = service.CalcPi((int)digitsUpDown.Value);
}

# # . 0 &9 % & # * 0 # . & 3 . # ,- # # # :%


% # % # % # # % * % %
# & 1 * # 3 % 9 % 0 # % # %&# # $ & >11B >11
# * 0 # # #

5 0 & % 1 & % # & & # 3 0 % 7

enum CalcState {
Pending,
Calculating,
Canceled,
}

CalcState state = CalcState.Pending;


localhost.CalcPiService service = new localhost.CalcPiService();

void calcButton_Click(object sender, System.EventArgs e) {


switch( state ) {
case CalcState.Pending:
state = CalcState.Calculating;
calcButton.Text = "Cancel";

// Start web service request


service.BeginCalcPi(
(int)digitsUpDown.Value,
new AsyncCallback(PiCalculated),
null);
break;

case CalcState.Calculating:
state = CalcState.Canceled;
calcButton.Enabled = false;
service.Abort(); // Fail all outstanding requests
break;

case CalcState.Canceled:
Debug.Assert(false);
break;
}
}

void PiCalculated(IAsyncResult res) {...}

4 de 6 02-12-2005 18:36
Safe, Simple Multithreading in Windows Forms, Part 3 (Wonders of Wi... http://msdn.microsoft.com/library/en-us/dnforms/html/winforms0123200...

# * 0 & % & # # % * * . * #
# * 0 " ' & & * # # % . %" ) #
&% # # # # # # & % # #
# # % 0 # & %

* # # & & 0 # # % "*


& # "' # $ 0% # # *# * % &
:% * 4% 0

# # # * # # # # % # &7

void PiCalculated(IAsyncResult res) {


try {
ShowPi(service.EndCalcPi(res));
}
catch( WebException ex ) {
ShowPi(ex.Message);
}
}

# # * & # %" ) * # % 3 & & #


-0 # % 0% * # % % -0* # # # * #
% % 0% % % *# # 1 * # # #
# # 9 # . # # # & 0 # %
# # 1 & # % 0 # ! &% ("

+ , ' $

delegate void ShowPiDelegate(string pi);

void ShowPi(string pi) {


if( this.InvokeRequired == false ) {
piTextBox.Text = pi;
state = CalcState.Pending;
calcButton.Text = "Calc";
calcButton.Enabled = true;
}
else {
ShowPiDelegate showPi = new ShowPiDelegate(ShowPi);
this.BeginInvoke(showPi, new object[] {pi});
}
}

# # # # # . 0 . :% . * % $ &
0 0 # % # # ,- # # % # 0
# # # # ,- # * . # # . #
,- # 0 % # & 0 #

" -
'% # % # %&# 0 & *-# # & % # # % #
! 0 # 1 & % # # ,- 0
&9 % & * % # ,- # % 0% # % % . # . # 4%
# # % # % # * # % & 9 & # #

5 de 6 02-12-2005 18:36
Safe, Simple Multithreading in Windows Forms, Part 3 (Wonders of Wi... http://msdn.microsoft.com/library/en-us/dnforms/html/winforms0123200...

# 0 # ; ! * # 0% # 1 . & 0 # %
* # # # # :% . # . & % 0
#

. # 1 0 # 0 # & 9 7
# +)(///D(+E" 6 # # 5 ! 0 #
# % # .

% * . %# ; & % = 3
. % . & ! "
#! - # 0 * # # % 0 * # F &# % 9 4 * #5
* & * . 0# 0 0 & 0 % # * # % 4 *
# 7BB #

6 9

& &7
/ 0 -
! % 08
/ ( ) G H D I E 8
6 =% &

/ ( ) G H D I E 8
, 1 2
+3 # # &

!" # $! % & % $ & ' # ( &

6 de 6 02-12-2005 18:36

You might also like