473,508 Members | 2,233 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Program problem, seems simple...

Okay, I'm a noob at C# and microsoft's IDE, but have a fairly long history
of programming (with, cough, Delphi). I'm writing a mobile app in C# with
Visual Studio 2005. I think there must be something fundamental that I'm
missing and could use a pointer in the right direction.

Below is a simplified version of a test program. I am using a namespace
provided from a dll file (used as MyNameSpace here). Anyway, I create a
component from within, which has a callback method. When I initiate the
process (button1_click), the callback happens just fine. However, I can not
seem to update any of the controls on the MainForm. As you will see, my
callback method has a call to Update Values. The call happens, but the
labels never get updated. However, initiating Button2_Click, will then call
UpdateValues and the labels will be updated.

It almost seems like my component is referencing a different instance of
MainForm. I would suspect this would be the behavior if I had not preceeded
my component with 'this' when creating it or the callback method. But, I
thought I got that right.

Anyway, anyone have an clues? Thanks for the help

Jim

================================================== ==========

using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MyNameSpace;

namespace MyTestApp
{
public partial class MainForm : Form
{
private MyClass MyVar;

public MainForm()
{
InitializeComponent();
Int Val1, Val2;
this.MyVar = new MyClass();
this.MyVar.OnResponse += new
MyClass.OnResponseHandler(this.MyResponseHandler);
}

private void button1_Click(object sender, EventArgs e)
{
MyVar.SendRequest();
}

private void button2_Click(object sender, EventArgs e)
{
UpdateValues();
}

private void MyResonseHandler(object sender,
nsoftware.IPWorks.SnmpmgrResponseEventArgs e)
{
Val1 = System.Int64.Parse(MyVar.Value1);
Val2 = System.Int64.Parse(MyVar.Value2);
UpdateValues();
}

private void UpdateValues()
{
MessageBox.Show("Updating Values");
label1.Text = Convert.ToString(Val1);
label2.Text = Convert.ToString(Val2);
}

}
}
Jun 22 '06 #1
10 1392
I tidied it up and added the missing code, and it works fine; are you sure
that the event is firing?

i.e. you should have something like:

public event EventHandler Response;
protected void OnResponse() {
EventHandler handler = Response;
if (handler != null) handler(this, EventArgs.Empty);
}
public void SendRequest() {
Value1--; // my random changes
Value2++;
OnResponse();
}

Oh - any by convention the event is named without the "On"; the "On"
preceeds the method used to fire the event - often protected and virtual.

Also - you might want to look at windows-forms bindings and making MyClass
implement INotifyPropertyChanged; this would allow you to tie MyClass to the
UI without any manual wiring required, yet get UI updates as the underlying
class is updated.

Marc
Jun 22 '06 #2
Scooby wrote:
Okay, I'm a noob at C# and microsoft's IDE, but have a fairly long history
of programming (with, cough, Delphi). I'm writing a mobile app in C# with
Visual Studio 2005. I think there must be something fundamental that I'm
missing and could use a pointer in the right direction.

Below is a simplified version of a test program. I am using a namespace
provided from a dll file (used as MyNameSpace here). Anyway, I create a
component from within, which has a callback method. When I initiate the
process (button1_click), the callback happens just fine. However, I can
not
seem to update any of the controls on the MainForm. As you will see, my
callback method has a call to Update Values. The call happens, but the
labels never get updated. However, initiating Button2_Click, will then
call UpdateValues and the labels will be updated.

It almost seems like my component is referencing a different instance of
MainForm. I would suspect this would be the behavior if I had not
preceeded
my component with 'this' when creating it or the callback method. But, I
thought I got that right.

Anyway, anyone have an clues? Thanks for the help

Jim

================================================== ==========

<snippedy-doo-dah>

Hi Jim,

Does your messagebox get shown? How are you invoking the callback? Are you
getting any exceptions about not being allowed to execute UI code from
another thread?

If you've got some cool cross-thread asynchronous code somewhere that
manages to invoke the callback from a thread other than the UI thread, then
you run into a problem. You'll need to invoke the code in the context of
the UI thread. Rename your 'UpdateValues' method to 'SafeUpdateValues' and
put the following code before it:

/// (Untested - I think my syntax is correct)
private delegate void SafeUpdateValuesDelegate ( );
private void UpdateValues ( )
{
if ( this.InvokeRequired )
this.Invoke( new SafeUpdateValuesDelegate( SafeUpdateValues ) );
else
SafeUpdateValues();
}
///

You should still make a call to UpdateValues, but that in turn will execute
the SafeUpdateValues method in the correct context.

Hope this helps,
-- Tom Spink
Jun 22 '06 #3
One other thought; it isn't shown in your code, but are you using multiple
threads? i.e. any of:

{delegate}.BeginInvoke
ThreadPool.QueueUserWorkItem
new Thread()
Anything else with "Begin..." in the name
?
If so, it it likely that the event is firing on a non-UI thread; any attempt
to talk to the Form's controls will then throw an exception, which may be
being absorbed by the calling code - especially if a matching "End..." isn't
being called (which in itself represents a leak - with the exception of
Control.EndInvoke).

If this is the case, post back and me (or somebody) will show you how to
switch threads in the form's event handler.

Marc
Jun 22 '06 #4
Thanks for the reply!

I initialize a stream writer on the server part to write something on the
socet that took the http request.
You mean that is something there that is not correct ?
Thanks again..


"Marc Gravell" <ma**********@gmail.com> wrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
I tidied it up and added the missing code, and it works fine; are you sure
that the event is firing?

i.e. you should have something like:

public event EventHandler Response;
protected void OnResponse() {
EventHandler handler = Response;
if (handler != null) handler(this, EventArgs.Empty);
}
public void SendRequest() {
Value1--; // my random changes
Value2++;
OnResponse();
}

Oh - any by convention the event is named without the "On"; the "On"
preceeds the method used to fire the event - often protected and virtual.

Also - you might want to look at windows-forms bindings and making MyClass
implement INotifyPropertyChanged; this would allow you to tie MyClass to
the UI without any manual wiring required, yet get UI updates as the
underlying class is updated.

Marc

Jun 22 '06 #5
Well, something somewhere isn't playing nice...

Again - the biggest question in tracking this is: what (if anything) is
actually /invoking/ the event?

Start by putting a break-point in the event handler, and see if it ever
hits; if it doesn't then you have your answer; find out why the event isn't
being fired... if it /does/ hit, then try adding something to the debug
trace to check if your handler is crashing (typically because of threading
issues):

public SomeHandler(object sender, EventArgs args) {
Debug.WriteLine("Starting", "SomeHandler");
try {
// your existing code
Debug.WriteLine("Complete", "SomeHandler");
} catch (Exception ex) {
Debug.WriteLine("Failed:", "SomeHandler");
Debug.WriteLine(ex.Message, ex.GetType().Name);
throw;
}
}

And then it is a case of knowing what thread it is firing on;
Jun 22 '06 #6
"Tom Spink" <ts****@gmail.com> wrote in message
news:OB**************@TK2MSFTNGP05.phx.gbl...
<snippedy-doo-dah>

Hi Jim,

Does your messagebox get shown? How are you invoking the callback? Are
you
getting any exceptions about not being allowed to execute UI code from
another thread?

If you've got some cool cross-thread asynchronous code somewhere that
manages to invoke the callback from a thread other than the UI thread,
then
you run into a problem. You'll need to invoke the code in the context of
the UI thread. Rename your 'UpdateValues' method to 'SafeUpdateValues'
and
put the following code before it:

/// (Untested - I think my syntax is correct)
private delegate void SafeUpdateValuesDelegate ( );
private void UpdateValues ( )
{
if ( this.InvokeRequired )
this.Invoke( new SafeUpdateValuesDelegate( SafeUpdateValues ) );
else
SafeUpdateValues();
}
///

You should still make a call to UpdateValues, but that in turn will
execute
the SafeUpdateValues method in the correct context.

Hope this helps,
-- Tom Spink


Tom,

Wow, thanks to you and everyone that has responded. Okay, this does appear
to be on the right path, although this code successfully locks up my PDA.
However, the test for Invoke Required does happen when in the callback
function. So, I think this is a good start. I'll have a read up on these
keywords and see what debugging I can do. If you have anything else to add,
that would be great.

To all.... To answer your questions and elaborate a bit. This was a
watered down version of the app as I just wanted this to appear as simple as
possbile for the sake of troubleshooting. The dll I am using is 3rd party
and I don't have source code. My code in particular is not multithreaded
yet (although the end result will be). However, I believe the component
probably is. So, the comments as such are probably correct.

Yes, the MessageBox that is included in the trial app does get shown.
However, if I put a Messagebox after the label updates, it does not get
shown when in the callback. So, that does show that there is an exception
somewhere. However, I am not given any indication that an exception has
occured.

Thanks again everyone. Let me know if you have any more tips.

Jim


Jun 22 '06 #7
"Marc Gravell" <ma**********@gmail.com> wrote in message
news:Oo**************@TK2MSFTNGP04.phx.gbl...
One other thought; it isn't shown in your code, but are you using multiple
threads? i.e. any of:

{delegate}.BeginInvoke
ThreadPool.QueueUserWorkItem
new Thread()
Anything else with "Begin..." in the name
?
If so, it it likely that the event is firing on a non-UI thread; any
attempt to talk to the Form's controls will then throw an exception, which
may be being absorbed by the calling code - especially if a matching
"End..." isn't being called (which in itself represents a leak - with the
exception of Control.EndInvoke).

If this is the case, post back and me (or somebody) will show you how to
switch threads in the form's event handler.

Marc


Marc,

Detail in another post (response to Tom). I believe this is probably the
case. So, just how do I switch back to the main thread?

Thanks,

Jim
Jun 22 '06 #8
Scooby wrote:
"Tom Spink" <ts****@gmail.com> wrote in message
news:OB**************@TK2MSFTNGP05.phx.gbl...
<snippedy-doo-dah>

Hi Jim,

Does your messagebox get shown? How are you invoking the callback? Are
you
getting any exceptions about not being allowed to execute UI code from
another thread?

If you've got some cool cross-thread asynchronous code somewhere that
manages to invoke the callback from a thread other than the UI thread,
then
you run into a problem. You'll need to invoke the code in the context of
the UI thread. Rename your 'UpdateValues' method to 'SafeUpdateValues'
and
put the following code before it:

/// (Untested - I think my syntax is correct)
private delegate void SafeUpdateValuesDelegate ( );
private void UpdateValues ( )
{
if ( this.InvokeRequired )
this.Invoke( new SafeUpdateValuesDelegate( SafeUpdateValues ) );
else
SafeUpdateValues();
}
///

You should still make a call to UpdateValues, but that in turn will
execute
the SafeUpdateValues method in the correct context.

Hope this helps,
-- Tom Spink


Tom,

Wow, thanks to you and everyone that has responded. Okay, this does
appear to be on the right path, although this code successfully locks up
my PDA. However, the test for Invoke Required does happen when in the
callback
function. So, I think this is a good start. I'll have a read up on these
keywords and see what debugging I can do. If you have anything else to
add, that would be great.

To all.... To answer your questions and elaborate a bit. This was a
watered down version of the app as I just wanted this to appear as simple
as
possbile for the sake of troubleshooting. The dll I am using is 3rd party
and I don't have source code. My code in particular is not multithreaded
yet (although the end result will be). However, I believe the component
probably is. So, the comments as such are probably correct.

Yes, the MessageBox that is included in the trial app does get shown.
However, if I put a Messagebox after the label updates, it does not get
shown when in the callback. So, that does show that there is an exception
somewhere. However, I am not given any indication that an exception has
occured.

Thanks again everyone. Let me know if you have any more tips.

Jim


Hi Jim,

Interesting that your code locks up. There's another way to execute code in
the context of the UI thread, it's slightly more complex, however:

using System.Threading;

public class MainForm : Form
{
private SynchronizationContext _context;

public MainForm ( )
{
_context = SynchronizationContext.Current;

if ( _context == null )
_context = new SynchronizationContext();

// Other constructor code
}

...

public void UpdateValues ()
{
if ( this.InvokeRequired )
{
_context.Send( delegate
{
SafeUpdateValues();
}, null );
}
else
SafeUpdateValues();
}

private void SafeUpdateValues ( )
{
...
}
}

So, I've put an ellipsis in where the original code should be. Again this
makes use of the 'SafeUpdateValues' routine, to contain the actual updating
code and the "unsafe" routine 'UpdateValues'.

Let us know if you have any problems,
-- Tom Spink
Jun 22 '06 #9
Tom has already shown 2 ways of doing this

Marc
Jun 23 '06 #10
"Tom Spink" <ts****@gmail.com> wrote in message
news:O5**************@TK2MSFTNGP02.phx.gbl...
Interesting that your code locks up. There's another way to execute code
in
the context of the UI thread, it's slightly more complex, however:

using System.Threading;

public class MainForm : Form
{
private SynchronizationContext _context;

public MainForm ( )
{
_context = SynchronizationContext.Current;

if ( _context == null )
_context = new SynchronizationContext();

// Other constructor code
}

...

public void UpdateValues ()
{
if ( this.InvokeRequired )
{
_context.Send( delegate
{
SafeUpdateValues();
}, null );
}
else
SafeUpdateValues();
}

private void SafeUpdateValues ( )
{
...
}
}

So, I've put an ellipsis in where the original code should be. Again this
makes use of the 'SafeUpdateValues' routine, to contain the actual
updating
code and the "unsafe" routine 'UpdateValues'.

Let us know if you have any problems,
-- Tom Spink


Well, Tom... Again, good info, but it doesn't seem to do it for me.
Apparently, this is not available in the Compact Framework. Arg. But, I
have found a work around. Instead of having the callback, I can have the
component wait for a response. It locks up the app during the call (really
only when it doesn't get a response - until the timeout), but I can now plan
on placing the component itself in a separate thread, which I had planned on
doing anyway to accomplish mulitple instances. At least I can manage the
thread process at that point rather than relying on the component to do it.

Anyway, I have learned a lot here that will help in the process. I should
be able to use the commands that you provided when I do it that way. So,
thanks for everyone's info.

Jim


Jun 23 '06 #11

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

Similar topics

6
4948
by: hoover_richard | last post by:
I am a newbie to C++ and I need help with a simple program I am trying to write. My program is designed to print all of the odd integers contained in an array and output the sum of the odd...
1
1513
by: Rhino | last post by:
What is the correct way to notify the tech writers that one of the sample programs has errors in it? Unless I am mistaken, there is an error in the DtLob.java program in the V8.1 Java/JDBC...
7
4111
by: jmac | last post by:
Greetings fellow programmers, I have created a C program that has a few bugs and would like to get some help with working them out. Here is a list of the problems that I am experiencing: -...
3
2152
by: Kerry | last post by:
I need some advice regarding a coding requirement that may suggest the need for an object oriented solution. The code fragments presented here attempt to solve the problem in C. The problem: ...
4
1480
by: Denise Mills | last post by:
Hi, On my previous Windows 98 machine, I wrote a simple C program that takes two text files as input, performs some calculations, then produces a text file that contains the results. It worked...
43
3382
by: davidkoree | last post by:
I mean not about cookie. Does it have something to do with operating system or browser plugin? I appreciate any help.
9
4401
by: Tyler | last post by:
Hello All: I am currently working on a project to create an FEM model for school. I was thinking about using wxPython to gather the 12 input variables from the user, then, after pressing the...
39
1970
by: mike3 | last post by:
Hi. I was writing a program in C++ that generates fractals. I got this weird bug though right now that's holding it up and was wondering if you could help. Anyway, it seems that when this...
13
1611
by: Thomas Neubauer | last post by:
Hello, i am learning c# and have created now a simple project that just creates 6 random numbers. My form includes a button and 6 labels for the random numbers. The program seems to work...
17
2679
by: LittleRob | last post by:
I'm having problems using Windows Task scheduler (or AT or SCHTASKS) to run a VB.NET program unattended. I'm able to reduce it to some really simple code that still fails My program has a Sub...
0
7123
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7326
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
5053
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4707
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3194
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3182
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1557
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
766
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
418
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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

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