I'm having a problem running a C# multithreaded application on Windows CE 5.0. The code I'm trying to execute is the source code of the MSDN article: "Safe, Simple Multithreading in Windows Forms, Part 3" , January 2003, written by Chris Sells (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...). The source files consist of 'AsynchCalcPi.cs' and 'NineDigitsOfPiAt.cs' found in winforms01232003_sample\ch13\LongRunningOperations\. (For VS2005 users: Start a new Windows CE project with Compact Framework 2.0 installed and do some copy and past to get it running).
The code demonstrates a thread safe 'message passing model', in which a long running operation (the calculation of n digits of pi) is performed on a worker thread. Everything in the source code is supported by the .Net Compact Framework 2.0 so this code should run just as well on both Windows CE and Windows XP. At least so I thought.
The problem is that the application executes just fine on Windows XP (thanks to MSIL), but I'm not able to get it running on Windows CE 5.0. Strange, isn't it?
What happens is that when i deploy the application from Visual Studio 2005 on the Windows CE target device, the application starts up by showing a form in which you can type the number of decimals of pi you want to compute and a button to start and cancel the computations. When pressing the start button a worker thread is started from the thread pool by calling BeginInvok and set to do the computations.
This is also where the application fails on Windows CE: When pressing the start button a "NotSupportedException" is thrown and the Visual Studio 2005 debugger indicates that this is caused by Application.Run(new AsynchCalcPiForm()); in the main method.
This I don't understand. The Windows Form is simpy launched from the default 'Program.cs' file containing only the main method with the above mentioned statement. What could be the problem here? Why is this working on Windows XP but not Windows CE?
PS This question was posted under Mobile and Embedded Development\Windows CE>Application Development but I was adviced to post it here instead.
The exception is thrown elsewhere, probably in the worker thread itself. We need to see more code. You could also try adding some try/catch blocks in the thread proc to find it.
-Chris
"GT" <G...@discussions.microsoft.com> wrote in message
> I'm having a problem running a C# multithreaded application on Windows CE > 5.0. > The code I'm trying to execute is the source code of the MSDN article: > "Safe, Simple Multithreading in Windows Forms, Part 3" , January 2003, > written by Chris Sells > (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...). > The source files consist of 'AsynchCalcPi.cs' and 'NineDigitsOfPiAt.cs' > found in > winforms01232003_sample\ch13\LongRunningOperations\. > (For VS2005 users: Start a new Windows CE project with Compact Framework > 2.0 > installed and do some copy and past to get it running).
> The code demonstrates a thread safe 'message passing model', in which a > long > running operation (the calculation of n digits of pi) is performed on a > worker thread. > Everything in the source code is supported by the .Net Compact Framework > 2.0 > so this code should run just as well on both Windows CE and Windows XP. At > least so I thought.
> The problem is that the application executes just fine on Windows XP > (thanks > to MSIL), but I'm not able to get it running on Windows CE 5.0. Strange, > isn't it?
> What happens is that when i deploy the application from Visual Studio 2005 > on the Windows CE target device, the application starts up by showing a > form > in which you can type the number of decimals of pi you want to compute and > a > button to start and cancel the computations. > When pressing the start button a worker thread is started from the thread > pool by calling BeginInvok and set to do the computations.
> This is also where the application fails on Windows CE: When pressing the > start button a "NotSupportedException" is thrown and the Visual Studio > 2005 > debugger indicates that this is caused by > Application.Run(new AsynchCalcPiForm()); > in the main method.
> This I don't understand. The Windows Form is simpy launched from the > default > 'Program.cs' file containing only the main method with the above mentioned > statement. > What could be the problem here? > Why is this working on Windows XP but not Windows CE?
> PS This question was posted under Mobile and Embedded > Development\Windows CE>Application Development but I was adviced to post > it here instead.
You will have to download the code from MSDN (see link in my original post). The example is small and nice so it shouldn't take too long to compile and get it running. If you do so you will see that the described problem is caused by the folowing call in AsynchCalcPiForm.cs >calcButton_Click : calcPi.BeginInvoke((int)digitsUpDown.Value, null, null); This call does however not throw any exceptions, because adding a try{} catch{Exception e} statement never causes the catch{} loop to be executed. Instead the VS2005 debugger indicates the NotSupportedException caused by Application.Run() in main() as before. Please take a look at the source code. It would make this a lot easier.
"<ctacke/>" wrote: > The exception is thrown elsewhere, probably in the worker thread itself. We > need to see more code. You could also try adding some try/catch blocks in > the thread proc to find it.
> > I'm having a problem running a C# multithreaded application on Windows CE > > 5.0. > > The code I'm trying to execute is the source code of the MSDN article: > > "Safe, Simple Multithreading in Windows Forms, Part 3" , January 2003, > > written by Chris Sells > > (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...). > > The source files consist of 'AsynchCalcPi.cs' and 'NineDigitsOfPiAt.cs' > > found in > > winforms01232003_sample\ch13\LongRunningOperations\. > > (For VS2005 users: Start a new Windows CE project with Compact Framework > > 2.0 > > installed and do some copy and past to get it running).
> > The code demonstrates a thread safe 'message passing model', in which a > > long > > running operation (the calculation of n digits of pi) is performed on a > > worker thread. > > Everything in the source code is supported by the .Net Compact Framework > > 2.0 > > so this code should run just as well on both Windows CE and Windows XP. At > > least so I thought.
> > The problem is that the application executes just fine on Windows XP > > (thanks > > to MSIL), but I'm not able to get it running on Windows CE 5.0. Strange, > > isn't it?
> > What happens is that when i deploy the application from Visual Studio 2005 > > on the Windows CE target device, the application starts up by showing a > > form > > in which you can type the number of decimals of pi you want to compute and > > a > > button to start and cancel the computations. > > When pressing the start button a worker thread is started from the thread > > pool by calling BeginInvok and set to do the computations.
> > This is also where the application fails on Windows CE: When pressing the > > start button a "NotSupportedException" is thrown and the Visual Studio > > 2005 > > debugger indicates that this is caused by > > Application.Run(new AsynchCalcPiForm()); > > in the main method.
> > This I don't understand. The Windows Form is simpy launched from the > > default > > 'Program.cs' file containing only the main method with the above mentioned > > statement. > > What could be the problem here? > > Why is this working on Windows XP but not Windows CE?
> > PS This question was posted under Mobile and Embedded > > Development\Windows CE>Application Development but I was adviced to post > > it here instead.
The exception is in the thread. You have no handler, so when it bubbles up, it comes out at the top - Application.Run. Trust me, Run is supported.
Sorry, but I'm not going to go to MSDN, download the sample and massage it into a device project just for the sake of helping you, and I doubt anyone else in the newsgroup will either. If you'd like to post the code, then we're happy to look at it for problems.
-- Chris Tacke OpenNETCF Consulting Managed Code in the Embedded World www.opennetcf.com --
"GT" <G...@discussions.microsoft.com> wrote in message
> You will have to download the code from MSDN (see link in my original > post). > The example is small and nice so it shouldn't take too long to compile and > get it running. > If you do so you will see that the described problem is caused by > the folowing call in AsynchCalcPiForm.cs >calcButton_Click : > calcPi.BeginInvoke((int)digitsUpDown.Value, null, null); > This call does however not throw any exceptions, because adding a try{} > catch{Exception e} statement never causes the catch{} loop to be executed. > Instead the VS2005 debugger indicates the NotSupportedException caused by > Application.Run() in main() as before. > Please take a look at the source code. It would make this a lot easier.
> "<ctacke/>" wrote:
>> The exception is thrown elsewhere, probably in the worker thread itself. >> We >> need to see more code. You could also try adding some try/catch blocks >> in >> the thread proc to find it.
>> > I'm having a problem running a C# multithreaded application on Windows >> > CE >> > 5.0. >> > The code I'm trying to execute is the source code of the MSDN article: >> > "Safe, Simple Multithreading in Windows Forms, Part 3" , January 2003, >> > written by Chris Sells >> > (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...). >> > The source files consist of 'AsynchCalcPi.cs' and 'NineDigitsOfPiAt.cs' >> > found in >> > winforms01232003_sample\ch13\LongRunningOperations\. >> > (For VS2005 users: Start a new Windows CE project with Compact >> > Framework >> > 2.0 >> > installed and do some copy and past to get it running).
>> > The code demonstrates a thread safe 'message passing model', in which a >> > long >> > running operation (the calculation of n digits of pi) is performed on a >> > worker thread. >> > Everything in the source code is supported by the .Net Compact >> > Framework >> > 2.0 >> > so this code should run just as well on both Windows CE and Windows XP. >> > At >> > least so I thought.
>> > The problem is that the application executes just fine on Windows XP >> > (thanks >> > to MSIL), but I'm not able to get it running on Windows CE 5.0. >> > Strange, >> > isn't it?
>> > What happens is that when i deploy the application from Visual Studio >> > 2005 >> > on the Windows CE target device, the application starts up by showing a >> > form >> > in which you can type the number of decimals of pi you want to compute >> > and >> > a >> > button to start and cancel the computations. >> > When pressing the start button a worker thread is started from the >> > thread >> > pool by calling BeginInvok and set to do the computations.
>> > This is also where the application fails on Windows CE: When pressing >> > the >> > start button a "NotSupportedException" is thrown and the Visual Studio >> > 2005 >> > debugger indicates that this is caused by >> > Application.Run(new AsynchCalcPiForm()); >> > in the main method.
>> > This I don't understand. The Windows Form is simpy launched from the >> > default >> > 'Program.cs' file containing only the main method with the above >> > mentioned >> > statement. >> > What could be the problem here? >> > Why is this working on Windows XP but not Windows CE?
>> > PS This question was posted under Mobile and Embedded >> > Development\Windows CE>Application Development but I was adviced to >> > post >> > it here instead.
The problem is that it's using BeginInvoke(). Not supported in .NET CF, although it's in the class definition. It's throwing a NotSupportedException, as expected.
Paul T.
"<ctacke/>" <ctacke[@]opennetcf[dot]com> wrote in message
> The exception is in the thread. You have no handler, so when it bubbles > up, it comes out at the top - Application.Run. Trust me, Run is > supported.
> Sorry, but I'm not going to go to MSDN, download the sample and massage it > into a device project just for the sake of helping you, and I doubt anyone > else in the newsgroup will either. If you'd like to post the code, then > we're happy to look at it for problems.
> -- > Chris Tacke > OpenNETCF Consulting > Managed Code in the Embedded World > www.opennetcf.com > --
> "GT" <G...@discussions.microsoft.com> wrote in message > news:11542385-2D84-4209-958C-C1FCF4C00BB9@microsoft.com... >> You will have to download the code from MSDN (see link in my original >> post). >> The example is small and nice so it shouldn't take too long to compile >> and >> get it running. >> If you do so you will see that the described problem is caused by >> the folowing call in AsynchCalcPiForm.cs >calcButton_Click : >> calcPi.BeginInvoke((int)digitsUpDown.Value, null, null); >> This call does however not throw any exceptions, because adding a try{} >> catch{Exception e} statement never causes the catch{} loop to be >> executed. >> Instead the VS2005 debugger indicates the NotSupportedException caused by >> Application.Run() in main() as before. >> Please take a look at the source code. It would make this a lot easier.
>> "<ctacke/>" wrote:
>>> The exception is thrown elsewhere, probably in the worker thread itself. >>> We >>> need to see more code. You could also try adding some try/catch blocks >>> in >>> the thread proc to find it.
>>> > I'm having a problem running a C# multithreaded application on Windows >>> > CE >>> > 5.0. >>> > The code I'm trying to execute is the source code of the MSDN article: >>> > "Safe, Simple Multithreading in Windows Forms, Part 3" , January 2003, >>> > written by Chris Sells >>> > (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...). >>> > The source files consist of 'AsynchCalcPi.cs' and >>> > 'NineDigitsOfPiAt.cs' >>> > found in >>> > winforms01232003_sample\ch13\LongRunningOperations\. >>> > (For VS2005 users: Start a new Windows CE project with Compact >>> > Framework >>> > 2.0 >>> > installed and do some copy and past to get it running).
>>> > The code demonstrates a thread safe 'message passing model', in which >>> > a >>> > long >>> > running operation (the calculation of n digits of pi) is performed on >>> > a >>> > worker thread. >>> > Everything in the source code is supported by the .Net Compact >>> > Framework >>> > 2.0 >>> > so this code should run just as well on both Windows CE and Windows >>> > XP. At >>> > least so I thought.
>>> > The problem is that the application executes just fine on Windows XP >>> > (thanks >>> > to MSIL), but I'm not able to get it running on Windows CE 5.0. >>> > Strange, >>> > isn't it?
>>> > What happens is that when i deploy the application from Visual Studio >>> > 2005 >>> > on the Windows CE target device, the application starts up by showing >>> > a >>> > form >>> > in which you can type the number of decimals of pi you want to compute >>> > and >>> > a >>> > button to start and cancel the computations. >>> > When pressing the start button a worker thread is started from the >>> > thread >>> > pool by calling BeginInvok and set to do the computations.
>>> > This is also where the application fails on Windows CE: When pressing >>> > the >>> > start button a "NotSupportedException" is thrown and the Visual Studio >>> > 2005 >>> > debugger indicates that this is caused by >>> > Application.Run(new AsynchCalcPiForm()); >>> > in the main method.
>>> > This I don't understand. The Windows Form is simpy launched from the >>> > default >>> > 'Program.cs' file containing only the main method with the above >>> > mentioned >>> > statement. >>> > What could be the problem here? >>> > Why is this working on Windows XP but not Windows CE?
>>> > PS This question was posted under Mobile and Embedded >>> > Development\Windows CE>Application Development but I was adviced to >>> > post >>> > it here instead.
Ok, let me get this straight: Are you saying the Delegate's BeginInvoke() is not supported by the .Net Compact Framework 2.0? From the MSDN documentation I had the impression that both the Control's and the Delegate's BeginInvoke() are supported by the .Net CF 2.0. Which is the case? The Visual Studio 2005 debugger does not complain about either.
> The problem is that it's using BeginInvoke(). Not supported in .NET CF, > although it's in the class definition. It's throwing a > NotSupportedException, as expected.
> Paul T.
> "<ctacke/>" <ctacke[@]opennetcf[dot]com> wrote in message > news:e5tfiu3yGHA.5048@TK2MSFTNGP05.phx.gbl... > > The exception is in the thread. You have no handler, so when it bubbles > > up, it comes out at the top - Application.Run. Trust me, Run is > > supported.
> > Sorry, but I'm not going to go to MSDN, download the sample and massage it > > into a device project just for the sake of helping you, and I doubt anyone > > else in the newsgroup will either. If you'd like to post the code, then > > we're happy to look at it for problems.
> > -- > > Chris Tacke > > OpenNETCF Consulting > > Managed Code in the Embedded World > > www.opennetcf.com > > --
> > "GT" <G...@discussions.microsoft.com> wrote in message > > news:11542385-2D84-4209-958C-C1FCF4C00BB9@microsoft.com... > >> You will have to download the code from MSDN (see link in my original > >> post). > >> The example is small and nice so it shouldn't take too long to compile > >> and > >> get it running. > >> If you do so you will see that the described problem is caused by > >> the folowing call in AsynchCalcPiForm.cs >calcButton_Click : > >> calcPi.BeginInvoke((int)digitsUpDown.Value, null, null); > >> This call does however not throw any exceptions, because adding a try{} > >> catch{Exception e} statement never causes the catch{} loop to be > >> executed. > >> Instead the VS2005 debugger indicates the NotSupportedException caused by > >> Application.Run() in main() as before. > >> Please take a look at the source code. It would make this a lot easier.
> >> "<ctacke/>" wrote:
> >>> The exception is thrown elsewhere, probably in the worker thread itself. > >>> We > >>> need to see more code. You could also try adding some try/catch blocks > >>> in > >>> the thread proc to find it.
> >>> > I'm having a problem running a C# multithreaded application on Windows > >>> > CE > >>> > 5.0. > >>> > The code I'm trying to execute is the source code of the MSDN article: > >>> > "Safe, Simple Multithreading in Windows Forms, Part 3" , January 2003, > >>> > written by Chris Sells > >>> > (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...). > >>> > The source files consist of 'AsynchCalcPi.cs' and > >>> > 'NineDigitsOfPiAt.cs' > >>> > found in > >>> > winforms01232003_sample\ch13\LongRunningOperations\. > >>> > (For VS2005 users: Start a new Windows CE project with Compact > >>> > Framework > >>> > 2.0 > >>> > installed and do some copy and past to get it running).
> >>> > The code demonstrates a thread safe 'message passing model', in which > >>> > a > >>> > long > >>> > running operation (the calculation of n digits of pi) is performed on > >>> > a > >>> > worker thread. > >>> > Everything in the source code is supported by the .Net Compact > >>> > Framework > >>> > 2.0 > >>> > so this code should run just as well on both Windows CE and Windows > >>> > XP. At > >>> > least so I thought.
> >>> > The problem is that the application executes just fine on Windows XP > >>> > (thanks > >>> > to MSIL), but I'm not able to get it running on Windows CE 5.0. > >>> > Strange, > >>> > isn't it?
> >>> > What happens is that when i deploy the application from Visual Studio > >>> > 2005 > >>> > on the Windows CE target device, the application starts up by showing > >>> > a > >>> > form > >>> > in which you can type the number of decimals of pi you want to compute > >>> > and > >>> > a > >>> > button to start and cancel the computations. > >>> > When pressing the start button a worker thread is started from the > >>> > thread > >>> > pool by calling BeginInvok and set to do the computations.
> >>> > This is also where the application fails on Windows CE: When pressing > >>> > the > >>> > start button a "NotSupportedException" is thrown and the Visual Studio > >>> > 2005 > >>> > debugger indicates that this is caused by > >>> > Application.Run(new AsynchCalcPiForm()); > >>> > in the main method.
> >>> > This I don't understand. The Windows Form is simpy launched from the > >>> > default > >>> > 'Program.cs' file containing only the main method with the above > >>> > mentioned > >>> > statement. > >>> > What could be the problem here? > >>> > Why is this working on Windows XP but not Windows CE?
> >>> > PS This question was posted under Mobile and Embedded > >>> > Development\Windows CE>Application Development but I was adviced to > >>> > post > >>> > it here instead.
Yes, that's what I'm saying. It's in the class signature (the method exists, in some sense), but any method that calls BeginInvoke() will generate a not-supported exception when that method is invoked. Delegates are supported and I don't see any problems with them, but BeginInvoke isn't. You can easily, or at least relatively easily, change the code to use Control.Invoke to call back into the UI thread. You can't pass a random set of parameters, but you can pass an EventArgs subclass which holds your extra parameters as fields, instead. It's not as clean as the desktop, but it works. Something like this:
-----
// Must use Invoke, not BeginInvoke, in .NET CF.
InvokeEventArgs args = new InvokeEventArgs(pi, totalDigits, digitsSoFar);
this.Invoke(new EventHandler(ShowProgress_invoke), new object[] { args });
> Ok, let me get this straight: > Are you saying the Delegate's BeginInvoke() is not supported by the .Net > Compact Framework 2.0? > From the MSDN documentation I had the impression that both the Control's > and > the Delegate's BeginInvoke() are supported by the .Net CF 2.0. Which is > the > case? > The Visual Studio 2005 debugger does not complain about either.
> "Paul G. Tobey [eMVP]" wrote:
>> The problem is that it's using BeginInvoke(). Not supported in .NET CF, >> although it's in the class definition. It's throwing a >> NotSupportedException, as expected.
>> Paul T.
>> "<ctacke/>" <ctacke[@]opennetcf[dot]com> wrote in message >> news:e5tfiu3yGHA.5048@TK2MSFTNGP05.phx.gbl... >> > The exception is in the thread. You have no handler, so when it >> > bubbles >> > up, it comes out at the top - Application.Run. Trust me, Run is >> > supported.
>> > Sorry, but I'm not going to go to MSDN, download the sample and massage >> > it >> > into a device project just for the sake of helping you, and I doubt >> > anyone >> > else in the newsgroup will either. If you'd like to post the code, >> > then >> > we're happy to look at it for problems.
>> > -- >> > Chris Tacke >> > OpenNETCF Consulting >> > Managed Code in the Embedded World >> > www.opennetcf.com >> > --
>> > "GT" <G...@discussions.microsoft.com> wrote in message >> > news:11542385-2D84-4209-958C-C1FCF4C00BB9@microsoft.com... >> >> You will have to download the code from MSDN (see link in my original >> >> post). >> >> The example is small and nice so it shouldn't take too long to compile >> >> and >> >> get it running. >> >> If you do so you will see that the described problem is caused by >> >> the folowing call in AsynchCalcPiForm.cs >calcButton_Click : >> >> calcPi.BeginInvoke((int)digitsUpDown.Value, null, null); >> >> This call does however not throw any exceptions, because adding a >> >> try{} >> >> catch{Exception e} statement never causes the catch{} loop to be >> >> executed. >> >> Instead the VS2005 debugger indicates the NotSupportedException caused >> >> by >> >> Application.Run() in main() as before. >> >> Please take a look at the source code. It would make this a lot >> >> easier.
>> >> "<ctacke/>" wrote:
>> >>> The exception is thrown elsewhere, probably in the worker thread >> >>> itself. >> >>> We >> >>> need to see more code. You could also try adding some try/catch >> >>> blocks >> >>> in >> >>> the thread proc to find it.
>> >>> > I'm having a problem running a C# multithreaded application on >> >>> > Windows >> >>> > CE >> >>> > 5.0. >> >>> > The code I'm trying to execute is the source code of the MSDN >> >>> > article: >> >>> > "Safe, Simple Multithreading in Windows Forms, Part 3" , January >> >>> > 2003, >> >>> > written by Chris Sells >> >>> > (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...). >> >>> > The source files consist of 'AsynchCalcPi.cs' and >> >>> > 'NineDigitsOfPiAt.cs' >> >>> > found in >> >>> > winforms01232003_sample\ch13\LongRunningOperations\. >> >>> > (For VS2005 users: Start a new Windows CE project with Compact >> >>> > Framework >> >>> > 2.0 >> >>> > installed and do some copy and past to get it running).
>> >>> > The code demonstrates a thread safe 'message passing model', in >> >>> > which >> >>> > a >> >>> > long >> >>> > running operation (the calculation of n digits of pi) is performed >> >>> > on >> >>> > a >> >>> > worker thread. >> >>> > Everything in the source code is supported by the .Net Compact >> >>> > Framework >> >>> > 2.0 >> >>> > so this code should run just as well on both Windows CE and Windows >> >>> > XP. At >> >>> > least so I thought.
>> >>> > The problem is that the application executes just fine on Windows >> >>> > XP >> >>> > (thanks >> >>> > to MSIL), but I'm not able to get it running on Windows CE 5.0. >> >>> > Strange, >> >>> > isn't it?
>> >>> > What happens is that when i deploy the application from Visual >> >>> > Studio >> >>> > 2005 >> >>> > on the Windows CE target device, the application starts up by >> >>> > showing >> >>> > a >> >>> > form >> >>> > in which you can type the number of decimals of pi you want to >> >>> > compute >> >>> > and >> >>> > a >> >>> > button to start and cancel the computations. >> >>> > When pressing the start button a worker thread is started from the >> >>> > thread >> >>> > pool by calling BeginInvok and set to do the computations.
>> >>> > This is also where the application fails on Windows CE: When >> >>> > pressing >> >>> > the >> >>> > start button a "NotSupportedException" is thrown and the Visual >> >>> > Studio >> >>> > 2005 >> >>> > debugger indicates that this is caused by >> >>> > Application.Run(new AsynchCalcPiForm()); >> >>> > in the main method.
>> >>> > This I don't understand. The Windows Form is simpy launched from >> >>> > the >> >>> > default >> >>> > 'Program.cs' file containing only the main method with the above >> >>> > mentioned >> >>> > statement. >> >>> > What could be the problem here? >> >>> > Why is this working on Windows XP but not Windows CE?
>> >>> > PS This question was posted under Mobile and Embedded >> >>> > Development\Windows CE>Application Development but I was adviced to >> >>> > post >> >>> > it here instead.
For .NET CF 2.0, BeginInvoke is supported. I use it in an app target for devices running .NET CF 2.0. SP1. However, my word is often questioned and more often questionable, so the following is straight from MS: --------------------------------------------- (http://msdn.microsoft.com/netframework/programming/netcf/default.aspx... Threads and the User Interface
The .NET Compact Framework 2.0 now supports asynchronous execution of a delegate on a user interface thread. Unlike the .NET Compact Framework 1.0 that supports only the Control.Invoke method (which synchronously executes a delegate on a control's owning thread), the .NET Compact Framework 2.0 provides Control.BeginInvoke that asynchronously executes a delegate on the control's owning thread. The Control.EndInvoke method is also provided. When called, the EndInvoke method returns the results of an asynchronous operation. ---------------------------------------------
I'd check which version of the CF is installed by running \Windows\cgacutil.exe. Re-install .NET CF if CF 2.0 is on the device.
> Yes, that's what I'm saying. It's in the class signature (the method exists, > in some sense), but any method that calls BeginInvoke() will generate a > not-supported exception when that method is invoked. Delegates are > supported and I don't see any problems with them, but BeginInvoke isn't. > You can easily, or at least relatively easily, change the code to use > Control.Invoke to call back into the UI thread. You can't pass a random set > of parameters, but you can pass an EventArgs subclass which holds your extra > parameters as fields, instead. It's not as clean as the desktop, but it > works. Something like this:
> -----
> // Must use Invoke, not BeginInvoke, in .NET CF.
> InvokeEventArgs args = new InvokeEventArgs(pi, totalDigits, > digitsSoFar);
> this.Invoke(new EventHandler(ShowProgress_invoke), new object[] { > args });
> public InvokeEventArgs(string _pi, int _digits, int _digitsSoFar)
> {
> pi = _pi;
> digits = _digits;
> digitsSoFar = _digitsSoFar;
> }
> }
> -----
> I'm not sure what the debugger has to do with anything.
> Paul T.
> "GT" <G...@discussions.microsoft.com> wrote in message > news:38B59EC7-4DA2-4D11-BED7-2B55AEE6DF21@microsoft.com... > > Ok, let me get this straight: > > Are you saying the Delegate's BeginInvoke() is not supported by the .Net > > Compact Framework 2.0? > > From the MSDN documentation I had the impression that both the Control's > > and > > the Delegate's BeginInvoke() are supported by the .Net CF 2.0. Which is > > the > > case? > > The Visual Studio 2005 debugger does not complain about either.
> > "Paul G. Tobey [eMVP]" wrote:
> >> The problem is that it's using BeginInvoke(). Not supported in .NET CF, > >> although it's in the class definition. It's throwing a > >> NotSupportedException, as expected.
> >> Paul T.
> >> "<ctacke/>" <ctacke[@]opennetcf[dot]com> wrote in message > >> news:e5tfiu3yGHA.5048@TK2MSFTNGP05.phx.gbl... > >> > The exception is in the thread. You have no handler, so when it > >> > bubbles > >> > up, it comes out at the top - Application.Run. Trust me, Run is > >> > supported.
> >> > Sorry, but I'm not going to go to MSDN, download the sample and massage > >> > it > >> > into a device project just for the sake of helping you, and I doubt > >> > anyone > >> > else in the newsgroup will either. If you'd like to post the code, > >> > then > >> > we're happy to look at it for problems.
> >> > -- > >> > Chris Tacke > >> > OpenNETCF Consulting > >> > Managed Code in the Embedded World > >> > www.opennetcf.com > >> > --
> >> > "GT" <G...@discussions.microsoft.com> wrote in message > >> > news:11542385-2D84-4209-958C-C1FCF4C00BB9@microsoft.com... > >> >> You will have to download the code from MSDN (see link in my original > >> >> post). > >> >> The example is small and nice so it shouldn't take too long to compile > >> >> and > >> >> get it running. > >> >> If you do so you will see that the described problem is caused by > >> >> the folowing call in AsynchCalcPiForm.cs >calcButton_Click : > >> >> calcPi.BeginInvoke((int)digitsUpDown.Value, null, null); > >> >> This call does however not throw any exceptions, because adding a > >> >> try{} > >> >> catch{Exception e} statement never causes the catch{} loop to be > >> >> executed. > >> >> Instead the VS2005 debugger indicates the NotSupportedException caused > >> >> by > >> >> Application.Run() in main() as before. > >> >> Please take a look at the source code. It would make this a lot > >> >> easier.
> >> >> "<ctacke/>" wrote:
> >> >>> The exception is thrown elsewhere, probably in the worker thread > >> >>> itself. > >> >>> We > >> >>> need to see more code. You could also try adding some try/catch > >> >>> blocks > >> >>> in > >> >>> the thread proc to find it.
> >> >>> > I'm having a problem running a C# multithreaded application on > >> >>> > Windows > >> >>> > CE > >> >>> > 5.0. > >> >>> > The code I'm trying to execute is the source code of the MSDN > >> >>> > article: > >> >>> > "Safe, Simple Multithreading in Windows Forms, Part 3" , January > >> >>> > 2003, > >> >>> > written by Chris Sells > >> >>> > (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...). > >> >>> > The source files consist of 'AsynchCalcPi.cs' and > >> >>> > 'NineDigitsOfPiAt.cs' > >> >>> > found in > >> >>> > winforms01232003_sample\ch13\LongRunningOperations\. > >> >>> > (For VS2005 users: Start a new Windows CE project with Compact > >> >>> > Framework > >> >>> > 2.0 > >> >>> > installed and do some copy and past to get it running).
> >> >>> > The code demonstrates a thread safe 'message passing model', in > >> >>> > which > >> >>> > a > >> >>> > long > >> >>> > running operation (the calculation of n digits of pi) is performed > >> >>> > on > >> >>> > a > >> >>> > worker thread. > >> >>> > Everything in the source code is supported by the .Net Compact > >> >>> > Framework > >> >>> > 2.0 > >> >>> > so this code should run just as well on both Windows CE and Windows > >> >>> > XP. At > >> >>> > least so I thought.
> >> >>> > The problem is that the application executes just fine on Windows > >> >>> > XP > >> >>> > (thanks > >> >>> > to MSIL), but I'm not able to get it running on Windows CE 5.0. > >> >>> > Strange, > >> >>> > isn't it?
> >> >>> > What happens is that when i deploy the application from Visual > >> >>> > Studio > >> >>> > 2005 > >> >>> > on the Windows CE target device, the application starts up by > >> >>> > showing > >> >>> > a > >> >>> > form > >> >>> > in which you can type the number of decimals of pi you want to > >> >>> > compute > >> >>> > and > >> >>> > a > >> >>> > button to start and cancel the computations. > >> >>> > When pressing the start button a worker thread is started from the > >> >>> > thread > >> >>> > pool by calling BeginInvok and set to do the computations.
> >> >>> > This is also where the application fails on Windows CE: When > >> >>> > pressing > >> >>> > the > >> >>> > start button a "NotSupportedException" is thrown and the Visual > >> >>> > Studio > >> >>> > 2005 > >> >>> > debugger indicates that this is caused by > >> >>> > Application.Run(new AsynchCalcPiForm()); > >> >>> > in the main method.
> >> >>> > This I don't understand. The Windows Form is simpy launched from > >> >>> > the > >> >>> > default > >> >>> > 'Program.cs' file containing only the main method with the above > >> >>> > mentioned > >> >>> > statement. > >> >>> > What could be the problem here? > >> >>> > Why is this working on Windows XP but not Windows CE?
> >> >>> > PS This question was posted under Mobile and Embedded > >> >>> > Development\Windows CE>Application Development but I was adviced to > >> >>> > post > >> >>> > it here instead.
Ooops... I meant I'd check which version of the CF is installed on the device by running \Windows\cgacutil.exe. Re-install .NET CF if CF 2.0 is NOT on the device.
Additionally, since this project was made a long time ago the references could be pointing to .NET CF 1.0 assemblies instead of .NET CF 2.0 assemblies. I'd would also recommend resetting all of the references in VS2005 to ensure the app is looking for the correct assemblies.
Functional Illiterate wrote: > For .NET CF 2.0, BeginInvoke is supported. I use it in an app target > for devices running .NET CF 2.0. SP1. However, my word is often > questioned and more often questionable, so the following is straight > from MS: > --------------------------------------------- > (http://msdn.microsoft.com/netframework/programming/netcf/default.aspx... > Threads and the User Interface
> The .NET Compact Framework 2.0 now supports asynchronous execution of a > delegate on a user interface thread. Unlike the .NET Compact Framework > 1.0 that supports only the Control.Invoke method (which synchronously > executes a delegate on a control's owning thread), the .NET Compact > Framework 2.0 provides Control.BeginInvoke that asynchronously executes > a delegate on the control's owning thread. The Control.EndInvoke method > is also provided. When called, the EndInvoke method returns the results > of an asynchronous operation. > ---------------------------------------------
> I'd check which version of the CF is installed by running > \Windows\cgacutil.exe. Re-install .NET CF if CF 2.0 is on the device.
> Good Luck
> Paul G. Tobey [eMVP] wrote: > > Yes, that's what I'm saying. It's in the class signature (the method exists, > > in some sense), but any method that calls BeginInvoke() will generate a > > not-supported exception when that method is invoked. Delegates are > > supported and I don't see any problems with them, but BeginInvoke isn't. > > You can easily, or at least relatively easily, change the code to use > > Control.Invoke to call back into the UI thread. You can't pass a random set > > of parameters, but you can pass an EventArgs subclass which holds your extra > > parameters as fields, instead. It's not as clean as the desktop, but it > > works. Something like this:
> > -----
> > // Must use Invoke, not BeginInvoke, in .NET CF.
> > public InvokeEventArgs(string _pi, int _digits, int _digitsSoFar)
> > {
> > pi = _pi;
> > digits = _digits;
> > digitsSoFar = _digitsSoFar;
> > }
> > }
> > -----
> > I'm not sure what the debugger has to do with anything.
> > Paul T.
> > "GT" <G...@discussions.microsoft.com> wrote in message > > news:38B59EC7-4DA2-4D11-BED7-2B55AEE6DF21@microsoft.com... > > > Ok, let me get this straight: > > > Are you saying the Delegate's BeginInvoke() is not supported by the .Net > > > Compact Framework 2.0? > > > From the MSDN documentation I had the impression that both the Control's > > > and > > > the Delegate's BeginInvoke() are supported by the .Net CF 2.0. Which is > > > the > > > case? > > > The Visual Studio 2005 debugger does not complain about either.
> > > "Paul G. Tobey [eMVP]" wrote:
> > >> The problem is that it's using BeginInvoke(). Not supported in .NET CF, > > >> although it's in the class definition. It's throwing a > > >> NotSupportedException, as expected.
> > >> Paul T.
> > >> "<ctacke/>" <ctacke[@]opennetcf[dot]com> wrote in message > > >> news:e5tfiu3yGHA.5048@TK2MSFTNGP05.phx.gbl... > > >> > The exception is in the thread. You have no handler, so when it > > >> > bubbles > > >> > up, it comes out at the top - Application.Run. Trust me, Run is > > >> > supported.
> > >> > Sorry, but I'm not going to go to MSDN, download the sample and massage > > >> > it > > >> > into a device project just for the sake of helping you, and I doubt > > >> > anyone > > >> > else in the newsgroup will either. If you'd like to post the code, > > >> > then > > >> > we're happy to look at it for problems.
> > >> > -- > > >> > Chris Tacke > > >> > OpenNETCF Consulting > > >> > Managed Code in the Embedded World > > >> > www.opennetcf.com > > >> > --
> > >> > "GT" <G...@discussions.microsoft.com> wrote in message > > >> > news:11542385-2D84-4209-958C-C1FCF4C00BB9@microsoft.com... > > >> >> You will have to download the code from MSDN (see link in my original > > >> >> post). > > >> >> The example is small and nice so it shouldn't take too long to compile > > >> >> and > > >> >> get it running. > > >> >> If you do so you will see that the described problem is caused by > > >> >> the folowing call in AsynchCalcPiForm.cs >calcButton_Click : > > >> >> calcPi.BeginInvoke((int)digitsUpDown.Value, null, null); > > >> >> This call does however not throw any exceptions, because adding a > > >> >> try{} > > >> >> catch{Exception e} statement never causes the catch{} loop to be > > >> >> executed. > > >> >> Instead the VS2005 debugger indicates the NotSupportedException caused > > >> >> by > > >> >> Application.Run() in main() as before. > > >> >> Please take a look at the source code. It would make this a lot > > >> >> easier.
> > >> >> "<ctacke/>" wrote:
> > >> >>> The exception is thrown elsewhere, probably in the worker thread > > >> >>> itself. > > >> >>> We > > >> >>> need to see more code. You could also try adding some try/catch > > >> >>> blocks > > >> >>> in > > >> >>> the thread proc to find it.
> > >> >>> > I'm having a problem running a C# multithreaded application on > > >> >>> > Windows > > >> >>> > CE > > >> >>> > 5.0. > > >> >>> > The code I'm trying to execute is the source code of the MSDN > > >> >>> > article: > > >> >>> > "Safe, Simple Multithreading in Windows Forms, Part 3" , January > > >> >>> > 2003, > > >> >>> > written by Chris Sells > > >> >>> > (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfo...). > > >> >>> > The source files consist of 'AsynchCalcPi.cs' and > > >> >>> > 'NineDigitsOfPiAt.cs' > > >> >>> > found in > > >> >>> > winforms01232003_sample\ch13\LongRunningOperations\. > > >> >>> > (For VS2005 users: Start a new Windows CE project with Compact > > >> >>> > Framework > > >> >>> > 2.0 > > >> >>> > installed and do some copy and past to get it running).
> > >> >>> > The code demonstrates a thread safe 'message passing model', in > > >> >>> > which > > >> >>> > a > > >> >>> > long > > >> >>> > running operation (the calculation of n digits of pi) is performed > > >> >>> > on > > >> >>> > a > > >> >>> > worker thread. > > >> >>> > Everything in the source code is supported by the .Net Compact > > >> >>> > Framework > > >> >>> > 2.0 > > >> >>> > so this code should run just as well on both Windows CE and Windows > > >> >>> > XP. At > > >> >>> > least so I thought.
> > >> >>> > The problem is that the application executes just fine on Windows > > >> >>> > XP > > >> >>> > (thanks > > >> >>> > to MSIL), but I'm not able to get it running on Windows CE 5.0. > > >> >>> > Strange, > > >> >>> > isn't it?
> > >> >>> > What happens is that when i deploy the application from Visual > > >> >>> > Studio > > >> >>> > 2005 > > >> >>> > on the Windows CE target device, the application starts up by > > >> >>> > showing > > >> >>> > a > > >> >>> > form > > >> >>> > in which you can type the number of decimals of pi you want to > > >> >>> > compute > > >> >>> > and > > >> >>> > a > > >> >>> > button to start and cancel the computations. > > >> >>> > When pressing the start button a worker thread is started from the > > >> >>> > thread > > >> >>> > pool by calling BeginInvok and set to do the computations.
> > >> >>> > This is also where the application fails on Windows CE: When > > >> >>> > pressing > > >> >>> > the > > >> >>> > start button a "NotSupportedException" is thrown and the Visual > > >> >>> > Studio > > >> >>> > 2005 > > >> >>> > debugger indicates that this is caused by > > >> >>> > Application.Run(new AsynchCalcPiForm()); > > >> >>> > in the main method.
> > >> >>> > This I don't understand. The Windows Form is simpy launched from > > >> >>> > the > > >> >>> > default > > >> >>> > 'Program.cs' file containing only the main method with the above > > >> >>> > mentioned > > >> >>> > statement. > > >> >>> > What could be the problem here? > > >> >>> > Why is this working on Windows XP but not Windows CE?
> > >> >>> > PS This question was posted under Mobile and Embedded > > >> >>> > Development\Windows CE>Application Development but I was adviced to > > >> >>> > post > > >> >>> > it here instead.
I've run 'cgautil.exe' on the Windows CE target and it verifies that I have Compact Framework 2.0 installed (more specifically version 2.0.5238.0). I have built the project by starting a new Win CE project in Visual Studio 2005 (of which I have CF2.0 installed) and merely copied the C# code of the original project. I've also cheched the project references and there are only references to CF 2.0 dlls. I also find it very hard to believe that BeginInvoke() is not supported by the CF2.0. If this really is the case, then MSDN is completely misleading. Perhaps the problem is related to something else. I will now post the source code below so that you can have a look and see if there is something else that may cause this problem:
/*AsynchCalcPiForm.cs *Windows Form lauched by Application.Run(new AsynchCalcPiForm()) * in Program.cs that only contains main(). * Aslo contains the class 'ShowProgressArgs' that keeps track of the * progress of the pi calculation performed by NineDigitsOfPi.cs */ using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Text; using System.Threading; using System.Diagnostics;
namespace CalcPI_Part3_CE { public partial class AsynchCalcPiForm : Form {
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 });
// Show progress asynchronously // IAsyncResult res = // BeginInvoke(showProgress, new object[] { pi, totalDigits, digitsSoFar, inoutCancel}); // // // Wait for results // while( !res.IsCompleted ) System.Threading.Thread.Sleep(100); // // // Harvest results // cancel = (bool)inoutCancel; // object methodResults = EndInvoke(res); // Do something with results... } }
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; } } }
// Calc button does double duty as Cancel button switch (state) { // Start a new calculation case CalcState.Pending: // Allow canceling state = CalcState.Calculating; calcButton.Text = "Cancel";
// Cancel a running calculation case CalcState.Calculating: state = CalcState.Canceled; calcButton.Enabled = false; break;
// Shouldn't be able to press Calc button while it's canceling case CalcState.Canceled: Debug.Assert(false); break; } }
}
}
// NineDigitsOfPi.cs
/* * Computation of the n'th decimal digit of pi with very little memory. * Written by Fabrice Bellard on January 8, 1997. * Ported to C# by Chris Sells on May 5, 2002. * * We use a slightly modified version of the method described by Simon * Plouffe in "On the Computation of the n'th decimal digit of various * transcendental numbers" (November 1996). We have modified the algorithm * to get a running time of O(n^2) instead of O(n^3log(n)^3). * * This program uses mostly integer arithmetic. It may be slow on some * hardwares where integer multiplications and divisons must be done * by software. */ using System; using System.Collections.Generic; using System.Text;
namespace CalcPI_Part3_CE { public class NineDigitsOfPi {
public static int mul_mod(long a, long b, int m) { return (int)((a * b) % m); }
// return the inverse of x mod y public static int inv_mod(int x, int y) { int q = 0; int u = x; int v = y; int a = 0; int c = 1; int t = 0;
do { q = v / u;
t = c; c = a - q * c; a = t;
t = u; u = v - q * u; v = t; } while (u != 0);
a = a % y; if (a < 0) a = y + a;
return a; }
// return (a^b) mod m public static int pow_mod(int a, int b, int m) { int r = 1; int aa = a;
while (true) { if ((b & 0x01) != 0) r = mul_mod(r, aa, m); b = b >> 1; if (b == 0) break; aa = mul_mod(aa, aa, m); }
return r; }
// return true if n is prime public static bool is_prime(int n) { if ((n % 2) == 0) return false;
int r = (int)(Math.Sqrt(n)); for (int i = 3; i <= r; i += 2) { if ((n % i) == 0) return false; }
return true; }
// return the prime number immediately after n public static int next_prime(int n) { do { n++; } while (!is_prime(n));
return n; }
public static int StartingAt(int n) { int av = 0; int vmax = 0; int N = (int)((n + 20) * Math.Log(10) / Math.Log(2)); int num = 0; int den = 0; int kq = 0; int kq2 = 0; int t = 0; int v = 0; int s = 0; double sum = 0.0;
for (int a = 3; a <= (2 * N); a = next_prime(a)) { vmax = (int)(Math.Log(2 * N) / Math.Log(a)); av = 1;
for (int i = 0; i < vmax; ++i) av = av * a;
s = 0; num = 1; den = 1; v = 0; kq = 1; kq2 = 1;
for (int k = 1; k <= N; ++k) { t = k; if (kq >= a) { do { t = t / a; --v; } while ((t % a) == 0);
kq = 0; }
++kq; num = mul_mod(num, t, av);
t = (2 * k - 1); if (kq2 >= a) { if (kq2 == a) { do { t = t / a; ++v; } while ((t % a)
...
I've gone through adding code step by step and the code runs fine until there's a call to BeginInvoke() in the _Click event handler. It's possible that there's a problem just in that one case, I suppose (calling from inside an event handler).
Paul T.
"GT" <G...@discussions.microsoft.com> wrote in message
> I've run 'cgautil.exe' on the Windows CE target and it verifies that I > have > Compact Framework 2.0 installed (more specifically version 2.0.5238.0). > I have built the project by starting a new Win CE project in Visual Studio > 2005 (of which I have CF2.0 installed) and merely copied the C# code of > the > original project. I've also cheched the project references and there are > only > references to CF 2.0 dlls. > I also find it very hard to believe that BeginInvoke() is not supported by > the CF2.0. If this really is the case, then MSDN is completely misleading. > Perhaps the problem is related to something else. I will now post the > source > code below so that you can have a look and see if there is something else > that may cause this problem:
> /*AsynchCalcPiForm.cs > *Windows Form lauched by Application.Run(new AsynchCalcPiForm()) > * in Program.cs that only contains main(). > * Aslo contains the class 'ShowProgressArgs' that keeps track of the > * progress of the pi calculation performed by NineDigitsOfPi.cs > */ > using System; > using System.Drawing; > using System.Collections; > using System.ComponentModel; > using System.Windows.Forms; > using System.Data; > using System.Text; > using System.Threading; > using System.Diagnostics;
> namespace CalcPI_Part3_CE > { > public partial class AsynchCalcPiForm : Form > {
> // Cancel a running calculation > case CalcState.Calculating: > state = CalcState.Canceled; > calcButton.Enabled = false; > break;
> // Shouldn't be able to press Calc button while it's > canceling > case CalcState.Canceled: > Debug.Assert(false); > break; > } > }
> } > }
> // NineDigitsOfPi.cs
> /* > * Computation of the n'th decimal digit of pi with very little memory. > * Written by Fabrice Bellard on January 8, 1997. > * Ported to C# by Chris Sells on May 5, 2002. > * > * We use a slightly modified version of the method described by Simon > * Plouffe in "On the Computation of the n'th decimal digit of various > * transcendental numbers" (November 1996). We have modified the algorithm > * to get a running time of O(n^2) instead of O(n^3log(n)^3). > * > * This program uses mostly integer arithmetic. It may be slow on some > * hardwares where integer multiplications and divisons must be done > * by software. > */ > using System; > using System.Collections.Generic; > using System.Text;
> namespace CalcPI_Part3_CE > { > public class NineDigitsOfPi > {
> public static int mul_mod(long a, long b, int m) > { > return (int)((a * b) % m); > }
> // return the inverse of x mod y > public static int inv_mod(int x, int y) > { > int q = 0; > int u = x; > int v = y; > int a = 0; > int c = 1; > int t = 0;
> do > { > q = v / u;
> t = c; > c = a - q * c; > a = t;
> t = u; > u = v - q * u; > v = t; > } > while (u != 0);
> a = a % y; > if (a < 0) a = y + a;
> return a; > }
> // return (a^b) mod m > public static int pow_mod(int a, int b, int m) > { > int r = 1; > int aa = a;
> while (true) > { > if ((b & 0x01) != 0) r = mul_mod(r, aa, m); > b = b >> 1; > if (b == 0) break; > aa = mul_mod(aa, aa, m); > }
> return r; > }
> // return true if n is prime > public static bool is_prime(int n) > { > if ((n % 2) == 0) return false;
> int r = (int)(Math.Sqrt(n)); > for (int i = 3; i <= r; i += 2) > { > if ((n % i) == 0) return false; > }
> return true; > }
> // return the prime number immediately after n > public static int next_prime(int n) > { > do > { > n++; > } > while (!is_prime(n));
> return n; > }
> public static int StartingAt(int n) > { > int av = 0; > int vmax = 0; > int N = (int)((n + 20) * Math.Log(10) / Math.Log(2)); > int num = 0; > int den = 0; > int kq = 0; > int kq2 = 0; > int t = 0; > int v = 0; > int s = 0; > double sum = 0.0;
> for (int a = 3; a <= (2 * N); a = next_prime(a)) > { > vmax = (int)(Math.Log(2 * N) / Math.Log(a)); > av = 1;
> for (int i = 0; i < vmax; ++i) av = av * a;
> s = 0; > num = 1; > den = 1; > v = 0; > kq = 1; > kq2 = 1;
> for (int k = 1; k <= N; ++k) > { > t = k; > if (kq >= a)
Alright, alright.. I took a look at that sample code and the BeginInvoke problem makes a bit more sense now. .NET CF 2.0 added support for *******Control.BeginInvoke()********. This differs from using BeginInvoke for delegates. Therein lies your main problem my friend.
CF is a different world than the full .NET. If you are looking to run sample code you should use samples targeted for .NET CF or else you run into problems like this. There are a number of things in this sample that simple will not run on .NET CF. To re-iterate what Paul said, intellisense will show you methods i.e. delegate.BeginInvoke, that the CF does not actually support.
If I were you I would rewrite the sample code. You can keep portions of it, but there are some fundamental changes that need to be made.
Again Paul is correct in saying, you can not use BeginInvoke the way it is currently used. The idea is to have the CalcPi method run on a background thread when the button is pressed. This will keep the UI free to do what a UI needs to do, process button presses, update progress bars, etc..
These are the changes I would make:
1 - Change the method signature of CalcPi to the following: void CalcPi (object valj) - This matches the signature of the WaitCallBack delegate needed for ThreadPool threads.
2 - The CalcState.Pending case needs to be changed for the button event handler as follows:
case CalcState.Pending: // Allow canceling state = CalcState.Calculating; calcButton.Text = "Cancel"l
// Asynch delegate method ThreadPool.QueueUserWorkItem(new WaitCallback(CalcPi), digitsUpDown.Value); break; - This creates a new (thread pool) thread which executes the CalcPi method. CalcPi needs to know how many digits of Pi to calculate. It gets this value from the digitsUpDown control. So you're passing digitsUpDown.Value to the method.
3 - Since you've changed the signature of CalcPi and passed it an object, you need to cast that back to an int within CalcPi. The first line of CalcPi should be as follows:
int digits = (int) val;
4 - The whole lesson of this sample is to (1) perform long calculations on non UI threads to maintain responsiveness and (2) show you that you cannot update the UI from a non-UI thread. In ShowProgress, a programatic check of the calling thread is done in, if (this.InvokeRequired == false). To test updating the progress bar asynchronously and the functionality of Begin invoke I would make the following changes in else block of ShowProgress:
else { ShowProgressHandler showProgress = new ShowProgressHandler(ShowProgress);
// Invoke(showProgress, new object[] { sender, e });
// Show progress asynchronously IAsyncResult res = BeginInvoke(showProgress, new object[] { pi, totalDigits, digitsSoFar, inoutCancel});
I didn't test any of this stuff... I'll leave that up to you. However, save some typo's, this should work and get you a little closer to making this sample work.
> I've gone through adding code step by step and the code runs fine until > there's a call to BeginInvoke() in the _Click event handler. It's possible > that there's a problem just in that one case, I suppose (calling from inside > an event handler).
> Paul T.
> "GT" <G...@discussions.microsoft.com> wrote in message > news:35A6F19D-F747-441C-BCA3-26B4CA005C31@microsoft.com... > > I've run 'cgautil.exe' on the Windows CE target and it verifies that I > > have > > Compact Framework 2.0 installed (more specifically version 2.0.5238.0). > > I have built the project by starting a new Win CE project in Visual Studio > > 2005 (of which I have CF2.0 installed) and merely copied the C# code of > > the > > original project. I've also cheched the project references and there are > > only > > references to CF 2.0 dlls. > > I also find it very hard to believe that BeginInvoke() is not supported by > > the CF2.0. If this really is the case, then MSDN is completely misleading. > > Perhaps the problem is related to something else. I will now post the > > source > > code below so that you can have a look and see if there is something else > > that may cause this problem:
> > /*AsynchCalcPiForm.cs > > *Windows Form lauched by Application.Run(new AsynchCalcPiForm()) > > * in Program.cs that only contains main(). > > * Aslo contains the class 'ShowProgressArgs' that keeps track of the > > * progress of the pi calculation performed by NineDigitsOfPi.cs > > */ > > using System; > > using System.Drawing; > > using System.Collections; > > using System.ComponentModel; > > using System.Windows.Forms; > > using System.Data; > > using System.Text; > > using System.Threading; > > using System.Diagnostics;
> > namespace CalcPI_Part3_CE > > { > > public partial class AsynchCalcPiForm : Form > > {
> I've attached my version, which does run, at least in the emulator. Follows > the code stubs that I posted previously. Everything updates while the > calculation is in progress. Note that I haven't made any effort to match > the controls used in the MS sample. I've got a TextEdit control to enter > the number of digits, no up/down control, etc., etc. Just a fair test of > the background thread work.
> Paul T.
> "Functional Illiterate" <functionalilliter...@gmail.com> wrote in message > news:1156963380.912560.83590@i42g2000cwa.googlegroups.com... > > Alright, alright.. I took a look at that sample code and the > > BeginInvoke problem makes a bit more sense now. .NET CF 2.0 added > > support for *******Control.BeginInvoke()********. This differs from > > using BeginInvoke for delegates. Therein lies your main problem my > > friend.
> > CF is a different world than the full .NET. If you are looking to run > > sample code you should use samples targeted for .NET CF or else you run > > into problems like this. There are a number of things in this sample > > that simple will not run on .NET CF. To re-iterate what Paul said, > > intellisense will show you methods i.e. delegate.BeginInvoke, that the > > CF does not actually support.
> > If I were you I would rewrite the sample code. You can keep portions > > of it, but there are some fundamental changes that need to be made.
> > Again Paul is correct in saying, you can not use BeginInvoke the way it > > is currently used. The idea is to have the CalcPi method run on a > > background thread when the button is pressed. This will keep the UI > > free to do what a UI needs to do, process button presses, update > > progress bars, etc..
> > These are the changes I would make:
> > 1 - Change the method signature of CalcPi to the following: > > void CalcPi (object valj) > > - This matches the signature of the WaitCallBack delegate needed for > > ThreadPool threads.
> > 2 - The CalcState.Pending case needs to be changed for the button event > > handler as follows:
> > case CalcState.Pending: > > // Allow canceling > > state = CalcState.Calculating; > > calcButton.Text = "Cancel"l
> > // Asynch delegate method > > ThreadPool.QueueUserWorkItem(new WaitCallback(CalcPi), > > digitsUpDown.Value); > > break; > > - This creates a new (thread pool) thread which executes the CalcPi > > method. CalcPi needs to know how many digits of Pi to calculate. It > > gets this value from the digitsUpDown control. So you're passing > > digitsUpDown.Value to the method.
> > 3 - Since you've changed the signature of CalcPi and passed it an > > object, you need to cast that back to an int within CalcPi. The first > > line of CalcPi should be as follows:
> > int digits = (int) val;
> > 4 - The whole lesson of this sample is to (1) perform long calculations > > on non UI threads to maintain responsiveness and (2) show you that you > > cannot update the UI from a non-UI thread. In ShowProgress, a > > programatic check of the calling thread is done in, if > > (this.InvokeRequired == false). To test updating the progress bar > > asynchronously and the functionality of Begin invoke I would make the > > following changes in else block of ShowProgress:
> > I didn't test any of this stuff... I'll leave that up to you. However, > > save some typo's, this should work and get you a little closer to > > making this sample work.
> > Good Luck.
> > Paul G. Tobey [eMVP] wrote: > >> I've gone through adding code step by step and the code runs fine until > >> there's a call to BeginInvoke() in the _Click event handler. It's > >> possible > >> that there's a problem just in that one case, I suppose (calling from > >> inside > >> an event handler).
> >> Paul T.
> >> "GT" <G...@discussions.microsoft.com> wrote in message > >> news:35A6F19D-F747-441C-BCA3-26B4CA005C31@microsoft.com... > >> > I've run 'cgautil.exe' on the Windows CE target and it verifies that I > >> > have > >> > Compact Framework 2.0 installed (more specifically version 2.0.5238.0). > >> > I have built the project by starting a new Win CE project in Visual > >> > Studio > >> > 2005 (of which I have CF2.0 installed) and merely copied the C# code of > >> > the > >> > original project. I've also cheched the project references and there > >> > are > >> > only > >> > references to CF 2.0 dlls. > >> > I also find it very hard to believe that BeginInvoke() is not supported > >> > by > >> > the CF2.0. If this really is the case, then MSDN is completely > >> > misleading. > >> > Perhaps the problem is related to something else. I will now post the > >> > source > >> > code below so that you can have a look and see if there is something > >> > else > >> > that may cause this problem:
> >> > /*AsynchCalcPiForm.cs > >> > *Windows Form lauched by Application.Run(new AsynchCalcPiForm()) > >> > * in Program.cs that only contains main(). > >> > * Aslo contains the class 'ShowProgressArgs' that keeps track of the > >> > * progress of the pi calculation performed by NineDigitsOfPi.cs > >> > */ > >> > using System; > >> > using System.Drawing; > >> > using System.Collections; > >> > using System.ComponentModel; > >> > using System.Windows.Forms; > >> > using System.Data; > >> > using System.Text; > >> > using System.Threading; > >> > using System.Diagnostics;
> >> > namespace CalcPI_Part3_CE > >> > { > >> > public partial class AsynchCalcPiForm : Form > >> > {
> >> > class ShowProgressArgs : EventArgs > >> > { > >> > public string Pi; > >> > public int TotalDigits; > >> > public int DigitsSoFar; > >> > public bool Cancel;
If you use a real newsreader, it's attached, just like an attachment would be found in your e-mail program. I don't know how to get it via the Web interface or even if it's possible.
Paul T.
"GT" <G...@discussions.microsoft.com> wrote in message
> Thank you very much guys. I will certainly try what you have suggested.
> Paul: Where can I find your attached version? (Can't find any links or > code > in your last post)
> "Paul G. Tobey [eMVP]" wrote:
>> I've attached my version, which does run, at least in the emulator. >> Follows >> the code stubs that I posted previously. Everything updates while the >> calculation is in progress. Note that I haven't made any effort to match >> the controls used in the MS sample. I've got a TextEdit control to enter >> the number of digits, no up/down control, etc., etc. Just a fair test of >> the background thread work.
>> Paul T.
>> "Functional Illiterate" <functionalilliter...@gmail.com> wrote in message >> news:1156963380.912560.83590@i42g2000cwa.googlegroups.com... >> > Alright, alright.. I took a look at that sample code and the >> > BeginInvoke problem makes a bit more sense now. .NET CF 2.0 added >> > support for *******Control.BeginInvoke()********. This differs from >> > using BeginInvoke for delegates. Therein lies your main problem my >> > friend.
>> > CF is a different world than the full .NET. If you are looking to run >> > sample code you should use samples targeted for .NET CF or else you run >> > into problems like this. There are a number of things in this sample >> > that simple will not run on .NET CF. To re-iterate what Paul said, >> > intellisense will show you methods i.e. delegate.BeginInvoke, that the >> > CF does not actually support.
>> > If I were you I would rewrite the sample code. You can keep portions >> > of it, but there are some fundamental changes that need to be made.
>> > Again Paul is correct in saying, you can not use BeginInvoke the way it >> > is currently used. The idea is to have the CalcPi method run on a >> > background thread when the button is pressed. This will keep the UI >> > free to do what a UI needs to do, process button presses, update >> > progress bars, etc..
>> > These are the changes I would make:
>> > 1 - Change the method signature of CalcPi to the following: >> > void CalcPi (object valj) >> > - This matches the signature of the WaitCallBack delegate needed for >> > ThreadPool threads.
>> > 2 - The CalcState.Pending case needs to be changed for the button event >> > handler as follows:
>> > case CalcState.Pending: >> > // Allow canceling >> > state = CalcState.Calculating; >> > calcButton.Text = "Cancel"l
>> > // Asynch delegate method >> > ThreadPool.QueueUserWorkItem(new WaitCallback(CalcPi), >> > digitsUpDown.Value); >> > break; >> > - This creates a new (thread pool) thread which executes the CalcPi >> > method. CalcPi needs to know how many digits of Pi to calculate. It >> > gets this value from the digitsUpDown control. So you're passing >> > digitsUpDown.Value to the method.
>> > 3 - Since you've changed the signature of CalcPi and passed it an >> > object, you need to cast that back to an int within CalcPi. The first >> > line of CalcPi should be as follows:
>> > int digits = (int) val;
>> > 4 - The whole lesson of this sample is to (1) perform long calculations >> > on non UI threads to maintain responsiveness and (2) show you that you >> > cannot update the UI from a non-UI thread. In ShowProgress, a >> > programatic check of the calling thread is done in, if >> > (this.InvokeRequired == false). To test updating the progress bar >> > asynchronously and the functionality of Begin invoke I would make the >> > following changes in else block of ShowProgress:
>> > I didn't test any of this stuff... I'll leave that up to you. However, >> > save some typo's, this should work and get you a little closer to >> > making this sample work.
>> > Good Luck.
>> > Paul G. Tobey [eMVP] wrote: >> >> I've gone through adding code step by step and the code runs fine >> >> until >> >> there's a call to BeginInvoke() in the _Click event handler. It's >> >> possible >> >> that there's a problem just in that one case, I suppose (calling from >> >> inside >> >> an event handler).
>> >> Paul T.
>> >> "GT" <G...@discussions.microsoft.com> wrote in message >> >> news:35A6F19D-F747-441C-BCA3-26B4CA005C31@microsoft.com... >> >> > I've run 'cgautil.exe' on the Windows CE target and it verifies that >> >> > I >> >> > have >> >> > Compact Framework 2.0 installed (more specifically version >> >> > 2.0.5238.0). >> >> > I have built the project by starting a new Win CE project in Visual >> >> > Studio >> >> > 2005 (of which I have CF2.0 installed) and merely copied the C# code >> >> > of >> >> > the >> >> > original project. I've also cheched the project references and there >> >> > are >> >> > only >> >> > references to CF 2.0 dlls. >> >> > I also find it very hard to believe that BeginInvoke() is not >> >> > supported >> >> > by >> >> > the CF2.0. If this really is the case, then MSDN is completely >> >> > misleading. >> >> > Perhaps the problem is related to something else. I will now post >> >> > the >> >> > source >> >> > code below so that you can have a look and see if there is something >> >> > else >> >> > that may cause this problem:
>> >> > /*AsynchCalcPiForm.cs >> >> > *Windows Form lauched by Application.Run(new AsynchCalcPiForm()) >> >> > * in Program.cs that only contains main(). >> >> > * Aslo contains the class 'ShowProgressArgs' that keeps track of the >> >> > * progress of the pi calculation performed by NineDigitsOfPi.cs >> >> > */ >> >> > using System; >> >> > using System.Drawing; >> >> > using System.Collections; >> >> > using System.ComponentModel; >> >> > using System.Windows.Forms; >> >> > using System.Data; >> >> > using System.Text; >> >> > using System.Threading; >> >> > using System.Diagnostics;
>> >> > namespace CalcPI_Part3_CE >> >> > { >> >> > public partial class AsynchCalcPiForm : Form >> >> > {
>> >> > class ShowProgressArgs : EventArgs >> >> > { >> >> > public string Pi; >> >> > public int TotalDigits; >> >> > public int DigitsSoFar; >> >> > public bool Cancel;