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);
}
}
} 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
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
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
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
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;
"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
"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
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
Tom has already shown 2 ways of doing this
Marc
"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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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...
|
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...
|
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:
-...
|
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:
...
|
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...
| |
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.
|
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...
|
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...
|
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...
|
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...
|
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...
| |
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,...
|
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...
|
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...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
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 ...
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
|
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...
| | |