I have a program with the following design
A couple of separate classes, each implementing one type of
algorithm
A windows form interface for providing input to run
different algorithms AND Speech Commands to do exactly the same.
Each algorithm is run by clicking a separate
button
Each algorithm raises some events (specific to the algorithms)
The event listeners in turn outputs through
The labels on the form AND through the speech API, speaks the results using speakers
The problem I am facing is that while debugging, if something goes wrong in one algorithm, other algorithms get initiated automatically sometimes. I want to be able to know what event listeners are registered with some event if any, at any point in time. I am using VS2008 with C#.
I also want to know if we use a Timer as a local variable and add an event listener to that timer in each class. Is is possible that the timer of one class triggers the listeners in other classes. I am new to this event listeners stuff, and not sure if I am missing some basic information that led me asking this question or its a problem with some ground.
i would suggest you get basics of debugging, i think this is all that you need for now. Here is a tutorial to basics of debugging. Get yourself familiar with F10 and F11 keys. by using breakpoints you can get the execution sequence of your algorithms.
2nd it is possible to that the timer of one class triggers the listeners in other classes Here is an example.
MyClass myClass = new MyClass();
Timer timer1 = new Timer();
timer1.Tick += myClass.TimerCallback; // subscribe to other's class method
timer1.Interval = 1000;
timer1.Start();
public class MyClass
{
public void TimerCallback(object sender, EventArgs eventArgs)
{
Console.WriteLine("Timer Called by: " + sender);
}
}
if you want to get list of callbacks subscribe to your callback use this answer, but i think you dont need that for now if you get use to debugging.
Related
I've read about VB6's threading model, and found this link very helpful.
With the following points in mind...
Do VB6 event handlers run in separate threads?
Not really, because there aren't separate threads. Your code runs on a single thread, wrapped in the service-like architecture I described above. Most of what you talk to that is threaded is other COM objects which have their own apartments. So to communicate back and forth, you are basically doing RPC calls when the threads talk to each other: you aren't directly manipulating them.
Among other things, the VB6 program had a timer that woke up every 4 seconds, manipulated some global variables and went back to sleep, while the main program was doing its thing. I can't understand why this didn't result in collisions.
The "timer" is on a separate thread created for the timer, but when it calls into your code, you are guaranteed not to interrupt any other functions, because the function calls are basically queued one at a time in the thread.
... I've attempted to implement VB6's event handling behavior in the code below.
ActionManager.cs
public class ActionManager : IDisposable
{
private readonly BlockingCollection<Action> ActionQueue = new BlockingCollection<Action>(new ConcurrentQueue<Action>());
public ActionManager()
{
}
public void Kickoff()
{
// Start consumer thread
new Thread(ExecuteLoop)
{
IsBackground = true
}.Start();
}
public void AddAction(Action action)
{
ActionQueue.Add(action);
}
private void ExecuteLoop()
{
// Blocks until new actions are available
foreach (var action in ActionQueue.GetConsumingEnumerable())
{
action.Invoke();
}
}
public void Dispose()
{
ActionQueue.CompleteAdding();
ActionQueue.Dispose();
}
}
MainForm.cs
public partial class MainForm : Form
{
public ActionManager actionManager = new ActionManager();
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load()
{
// Perform preparatory steps, such as initializing resources,
// configuring settings, etc.
// (Insert preparatory steps here)
// Once preparatory steps are complete, start the ActionManager
actionManager.Kickoff();
}
// Event handler for when the Timer's specified interval has elapsed
private void Timer_Tick(object sender, EventArgs e)
{
actionManager.AddAction(() => {
// (Insert timer event steps here)
});
}
// Event handler for when SomeButton is clicked
private void SomeButton_Click(object sender, EventArgs e)
{
actionManager.AddAction(() => {
// (Insert button click event steps here)
});
}
}
An ActionManager manages an event queue by executing each event one after the other. Any type of event, such as mouse clicks, timer ticks, network packet arrivals, and the like, will enqueue their respective event handling code to the event queue. This way, the code will run "on a single thread," which will also handle the problem of unsynchronized global variables.
Is this a correct implementation? Please share your thoughts!
What you have is a somewhat decent starting place for a custom message loop, if you were to begin writing your own UI framework from scratch. But you're using winforms, you're not writing your own UI framework from scratch. Winforms already has its own message loop that processes messages, and a mechanism for scheduling work to run in that loop. You don't need to create any of that from scratch. All of the events fired from the winforms controls will already be firing in the UI thread, so you don't need to create your own special UI thread and manage scheduling actions into it.
In fact doing so would cause problems, as you would end up having the UI thread that winforms is using to manage its UI objects, and you would have your second thread that you're creating. If you ever used any UI controls in that thread things would break as they are designed to only be used from the winforms UI thread.
(I figured I should ask in the comments first if my suspicion about a legacy app was right.)
Okay, time for the bad news: you should NOT do this. Please, please, please, do NOT do this. I'm telling you as a developer that has been in your shoes that this will NOT end well if you try to go down this road.
Here's what's going on. You've got a legacy app - and it probably does a lot of things that are very important for the company.
But the problem is, it's likely not written very well, it's cranky, and it did not port very well into the modern .NET world.
Now, you can try to go down the road of shoehorning .NET into the VB6 model of the world... but all you've done is kick the can down the road. You've still got a badly-written, cranky legacy app that you're still having to maintain - and worse, you're having to maintain the .NET-to-VB6-threading-approach as well.
I can guarantee you that the correct approach is to Redesign/Rearchitect it. Write out what it does, ask yourself if there's anything you can do to improve the process, and write it from scratch in .NET. Several reasons:
You're going to have a more stable end product
You're going to spend FAR less time maintaining the new product
You'd have to rearchitect the program eventually anyways.
If it helps, let me tell you a story of an old job I had. A coworker and I were both responsible for porting VB6 apps into .NET. He had a tire inspection app, and I had a rubber mixing app.
He tried porting his existing VB6 app into .NET, getting all the language
differences worked out, GUI/Thread issues altered, etc
I sat down with a rep from the user area, and went ahead just
rewriting the rubber mixing app.
... I was done much sooner than the coworker, my app was far more user-friendly, and it was a heck of a lot less of a maintenance issue.
Management likely will not like hearing advice that you should rewrite the whole thing. But you need to push and fight for this. If it helps, point out that most software dev time isn't on new coding, it's on maintaining existing software. It might take more time up front to get it rewritten (even that's not a given) but it'll pay for itself very quickly in the long run.
I'm currently building an application for iOS and Android using Xamarin and MonoTouch. In the application there is going to be a lot of data loaded from JSON, and therefore I wanted to incorporate a unified loader, an object that runs on application start to check whether it needs to re-download information or not.
The loading class is done and is fully functional, and has the following methods that I want to be able to bind events to. See below:
BeginLoading
ReloadPosts
ReloadLayers
ReloadRunners
FinishedLoading
These are all self contained and run in the loader class which I initiate in ViewDidLoad in my main screen (MainScreen.cs) using the following code:
var loader = new UnifiedLoader();
This starts the process of checking the local cache, last reload time etc and either starts the reloading process - posts, layers, runners or jumps straight to FinishedLoading.
What I'd like to be able to do is to listen for these "events" in some fashion, and I have no idea how to go about doing so. Please look below for an example.
var loader = new UnifiedLoader();
loader.LoadingDidBegin += () => {
Console.Out.WriteLine("Loading started");
// Display spinner or something...
};
loader.DidReloadPosts += () => {
Console.Out.WriteLine("Posts were reloaded");
// Update reloading percentage, show user...
};
loader.DidReloadLayers += () => {
Console.Out.WriteLine("Layers were reloaded");
// Update reloading percentage, show user...
};
loader.DidReloadRunners += () => {
Console.Out.WriteLine("Runners were reloaded");
// Update reloading percentage, show user...
};
loader.LoadingDidFinish += () => {
Console.Out.WriteLine("Loading finished");
// Remove spinner, proceed...
};
As of now I have no idea how I would go about implementing these events in the loading class. I've been searching and going through the API documentation but found nothing to aid me.
I would be more than thankful if someone could help me solve this.
Thanks in advance,
Jonathan
The preferred way would be to just write:
public EventHandler LoadingDidBegin;
This saves you from declaring the delegates and conforms to coding guidelines: http://msdn.microsoft.com/en-us/library/w369ty8x.aspx
I solved it by finding the Microsoft documentation for C# events. It was as simple as using the following code to register the event delegates and events.
This code goes outside of the class:
public delegate void LoadingDidBegin();
And this code goes inside the class:
public event LoadingDidBegin LoadingDidBegin;
And in the method where you want to invoke the event, call this:
// Trigger event:
if (this.CheckingDidBegin != null){
this.CheckingDidBegin ();
}
And last, in the class where you bind the event, bind the delegate like this:
var loader = new UnifiedLoader ();
loader.LoadingDidBegin += delegate {
// Do something here, show a HUD for instance...
};
loader.InitiateLoader ();
That's pretty much it, just remember to register the delegates before initiating the methods that carry the event triggers, otherwise they will just return null and you will get no feedback.
Good luck!
First, the apology: I'm new to posting questions on this site, so I apologize for formatting or information errors.I have seen many answers to taking data from a serial port dropped on a form and using it to populate text boxes, graphs, etc. on the main form, using "Invoke" because the serial port is running in a different thread.
I am trying to "generalize" some comm stuff we use all the time in to a class (yes, the old VB6 programmer is trying to grow up :-) and I'm having issues. I can do some things if I force a form name in the main program.cs and use the same namespace for the class, but this sorta defeats the purpose. I've also tried adding an event on the "received" even of the serial port in the class to raise an event on the main form. The event tries to get raised but a cross thread exception occurs.
The code at this point is quite large, so I'll try to "outline" it. In simplistic form, assuming I have a for called "Form1" which contains a text box called textbox1 and a class called "SerialThing":
Form1:
SerialThing mySerialThing ;
Form1_Load:
mySerialThing = new SerialThing();
DisplayData()
Textbox1.Text = "You Got Data!";
SerialThing:
Static SerialPort myDevice;
Init()
myDevice = new SerialPort;
myDevice.DataReceived += new SerialDataReceivedEventHandler(devicePort_DataReceived);
devicePort_DataReceived()
this.Invoke(new EventHandler(DisplayData));
The above will work if the serial port is placed on the main form, but not if created inside the class.
Again, sorry if too complex, or too simplistic. I am looking for an "easy" way to do this, but keep the class "generalized" (ideally not have to have the workspace names match, etc).
-Vin
There are many, many ways to do this. I'll present the classic approach using a custom event, delegates, and Invoke(), as I think it's important to understand that process. Once you've got this down, you can jump to some of the newer approaches.
First, in your SerialThing() class, you declare a Custom event to pass out data when it is received:
class SerialThing
{
public delegate void DataReceivedDelegate(string data);
public event DataReceivedDelegate DataReceived;
static SerialPort myDevice;
public SerialThing()
{
myDevice = new SerialPort();
myDevice.DataReceived += new SerialDataReceivedEventHandler(myDevice_DataReceived);
}
void myDevice_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// ... grab the data and place into a string called "data" ...
string data = "";
// raise our custom event:
if (DataReceived != null)
{
DataReceived(data);
}
}
}
Now, over in Form1, you subscribe to that custom event when you create the instance of SerialThing. Additionally, when that event is received, you marshal the call from the secondary thread to the main thread using InvokeRequired, Invoke, and a delegate:
public partial class Form1 : Form
{
SerialThing mySerialThing;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
mySerialThing = new SerialThing();
mySerialThing.DataReceived += new SerialThing.DataReceivedDelegate(mySerialThing_DataReceived);
}
private delegate void DataReceivedDelegate(string data);
void mySerialThing_DataReceived(string data)
{
if (this.InvokeRequired)
{
this.Invoke(new DataReceivedDelegate(mySerialThing_DataReceived), new Object[] { data });
}
else
{
textBox1.Text = data;
}
}
}
EDIT: In response to your comments below...
Think of a delegate as simply a "pointer to a method". When you execute the delegate, the associated method gets run.
The InvokeRequired() portion determines if the code is running in a different thread than the one that created the control. In this case, the control is the Form itself (this). If true is returned, then the event was received in a different thread. We then proceed to this.Invoke() line inside the true portion of the If block. Again this refers to the Form. Thus the Form is requesting to Invoke ("run") the passed delegate on the thread that created it (the main UI thread). We create a instance of the delegate that actually points to the same method we are already in resulting in a recursive call. The second parameter is simply an array of Object used to pass the parameters along with the delegate.
When Invoke() is run we end up re-entering the method because of the recursive call. At this point, however, the InvokeRequired() check will return false as we are now running in the main UI thread. Therefore we drop down into the false portion of the If statement where we update the TextBox. In this pattern it is safe to update an GUI controls in the else block of the If statement.
Note that a recursive call isn't necessary here. This is simply a style choice. We could have instead used a second "helper" function that the delegate pointed to, and Invoked that instead. The recursive approach reduces the number of methods required.
This is perhaps the most verbose approach to solving this type of problem. I like it, though, as it shows the flow of events and data, and movement between the threads.
We could shorten all the Form code to just this, using anonymous delegates:
private void Form1_Load(object sender, EventArgs e)
{
mySerialThing = new SerialThing();
mySerialThing.DataReceived += delegate (string data)
{
this.Invoke((MethodInvoker)(delegate() { textBox1.Text = data; }));
};
}
I don't know about you, but as a former VB6 programmer myself, that just looks weird when you first see that type of thing.
I've also used components that I know have things running in different
threads, yet the "form code" has never had to use the delegate stuff,
so maybe there's something that can be buried into the class?
Yes, it's possible to bake some "magic" into a class so that it raises events already on the main UI thread, thus not requiring any Invoke() calls. One way to do this is thru using a SynchronizationContext.
Another possibility for approaching this type of problem would be to use a BackgroundWorker() control which has events such as ProgressChanged() and RunWorkerCompleted() that are raised in the main UI thread for you (they do the necessary invoking type stuff under the hood for you).
I am maintaining some code which has two FileSystemWatcher events that makes it difficult to debug (and it has an error). So my idea is to simplify the code by making the execution sequential. Pretty much like this:
Main method
1) normal code here
2) enable event 1, let it check for files, disable it when it is done running once
3) enable event 2, let it check for files, disable it when it is done running once
Then the database logs would make more sense. I would be able to see which part of the program that is doing something wrong.
private void InitializeFileSystemWatcher()
{
this.MessageMonitor = new FileSystemWatcher(this.MessagePath, this.MessageFilter);
this.MessageMonitor.IncludeSubdirectories = true; // Recursive.
this.MessageMonitor.Created += new FileSystemEventHandler(OnMessageReceived);
this.MessageMonitor.EnableRaisingEvents = true;
}
From the main, I can set the EnableRaisingEvents=true to EnableRaisingEvents=false. Both events indexes the files in some folder and enacts a callback method.
My question is this: If the event is currently executing and I set EnableRaisingEvents=false, will it pause or continue to execute until it finishes?
If it does continue, I figure just to have a bool doRUN variable set at beginning and the end of the event as a check for the main method.
You should just detach the event handler after you check to make sure that it is working properly and then instantiate the second FileSystemWatcher.
Inside of the OnMessageReceived you could od something like
public void OnMessageRecieved(Object sender, Events e) //Not the real signature
{
MessageMonitor.Created -= OnMessageReceived();
//Do Your things
OtherMessageMonitor.Created += OnMessageReceived();
}
I developed a C# class library, some of their methods shows information of its processing progress because they read and write millions of records, and the user asked for knowing how the process is going and the time they should wait.
Using dependency injection to avoid the "if console app write progress on console else if WPF app display progress bar", (1) I have got the displaying on the console the time for every one million records processed if the method is invoked from a console application and (2) I have got the displaying a progress bar on a GUI if the method is invoked from a WPF application.
The question here is, is it a good practice what I am doing or, is there better/correct alternative to this matter?
My best regards.
Please don't do this. If you are building a class library, you should make zero assumptions about the UI is interacting with the user.
Your solution sounds like it might work if you have a console window or a WPF application, but what if it's being called from a website or inside a service? I've seen many a service get brought down beause some rogue class library was trying to display a dialog but there was nobody around to click OK.
The better solution is to simply raise an event whenever you want to report some progress, and let the consuming UI application worry how it wants to display that progress to the user.
See how the BackgroundWorker class works for a good model of this: http://msdn.microsoft.com/en-us/library/8xs8549b.aspx
I wouldn't expect a class library to display the progress itself. I'd expect it provide hooks - probably in the form of events - so that whatever using the class library can display that information in the most appropriate form.
Quite how much control you want to give over that (e.g. report to me on every item or every N items) is a matter you'll have to work out for yourself - but it should be fairly easy for a handler to work that sort of thing out for itself.
Here's an example of raising events, this code will go in your class that is doing the work on the background thread. The MessageEventsArgs derives from EventArgs (MessageEventArgs : EventArgs) so custom information can be passed to the caller. This isn't required, one could use EventArgs e as well.
public delegate void SchemaProcessorMessageEventHandler(object sender, MessageEventArgs e);
public event SchemaProcessorMessageEventHandler SchemaProcessorMessage;
protected virtual void OnSchemaProcessorMessage(MessageEventArgs e)
{
if (SchemaProcessorMessage != null)
{
SchemaProcessorMessage(this, e);
}
}
Now in your caller (UI) set up the event listener. Remove the event listener -= when finished.
_SchemaProcessor = new ServerSchemaUtilityFramework.SchemaProcessor();
_SchemaProcessor.SchemaProcessorMessage += new ServerSchemaUtilityFramework.SchemaProcessor.SchemaProcessorMessageEventHandler(sp_SchemaProcessorMessage);
void sp_SchemaProcessorMessage(object sender, ServerSchemaUtilityFramework.MessageEventArgs e)
{
//Update the UI, if on background will need to (!this.Dispatcher.CheckAccess())
}