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();
}
Related
In .NET, Windows Forms have an event that fires before the Form is loaded (Form.Load), but there is no corresponding event that is fired AFTER the form has loaded. I would like to execute some logic after the form has loaded.
Can anyone advise on a solution?
You could use the "Shown" event: MSDN - Form.Shown
"The Shown event is only raised the first time a form is displayed; subsequently minimizing, maximizing, restoring, hiding, showing, or invalidating and repainting will not raise this event."
I sometimes use (in Load)
this.BeginInvoke((MethodInvoker) delegate {
// some code
});
or
this.BeginInvoke((MethodInvoker) this.SomeMethod);
(change "this" to your form variable if you are handling the event on an instance other than "this").
This pushes the invoke onto the windows-forms loop, so it gets processed when the form is processing the message queue.
[updated on request]
The Control.Invoke/Control.BeginInvoke methods are intended for use with threading, and are a mechanism to push work onto the UI thread. Normally this is used by worker threads etc. Control.Invoke does a synchronous call, where-as Control.BeginInvoke does an asynchronous call.
Normally, these would be used as:
SomeCodeOrEventHandlerOnAWorkerThread()
{
// this code running on a worker thread...
string newText = ExpensiveMethod(); // perhaps a DB/web call
// now ask the UI thread to update itself
this.Invoke((MethodInvoker) delegate {
// this code runs on the UI thread!
this.Text = newText;
});
}
It does this by pushing a message onto the windows message queue; the UI thread (at some point) de-queues the message, processes the delegate, and signals the worker that it completed... so far so good ;-p
OK; so what happens if we use Control.Invoke / Control.BeginInvoke on the UI thread? It copes... if you call Control.Invoke, it is sensible enough to know that blocking on the message queue would cause an immediate deadlock - so if you are already on the UI thread it simply runs the code immediately... so that doesn't help us...
But Control.BeginInvoke works differently: it always pushes work onto the queue, even it we are already on the UI thread. This makes a really simply way of saying "in a moment", but without the inconvenience of timers etc (which would still have to do the same thing anyway!).
First time it WILL NOT start "AfterLoading",
It will just register it to start NEXT Load.
private void Main_Load(object sender, System.EventArgs e)
{
//Register it to Start in Load
//Starting from the Next time.
this.Activated += AfterLoading;
}
private void AfterLoading(object sender, EventArgs e)
{
this.Activated -= AfterLoading;
//Write your code here.
}
I had the same problem, and solved it as follows:
Actually I want to show Message and close it automatically after 2 second. For that I had to generate (dynamically) simple form and one label showing message, stop message for 1500 ms so user read it. And Close dynamically created form. Shown event occur After load event. So code is
Form MessageForm = new Form();
MessageForm.Shown += (s, e1) => {
Thread t = new Thread(() => Thread.Sleep(1500));
t.Start();
t.Join();
MessageForm.Close();
};
You could also try putting your code in the Activated event of the form, if you want it to occur, just when the form is activated. You would need to put in a boolean "has executed" check though if it is only supposed to run on the first activation.
Here are some details added to previous correct answers, especially the one by Matthias Schippling.
Add an event handler in Form1_Load, like this:
private void Form1_Load(object sender, EventArgs e)
{
this.Shown += new EventHandler(Form1_Shown);
}
Next, add the method that will do something with the code
private void Form1_Shown(Object sender, EventArgs e)
{
draw_on_my_form_or_some_other_action();
}
This an old question and depends more upon when you need to start your routines. Since no one wants a null reference exception it is always best to check for null first then use as needed; that alone may save you a lot of grief.
The most common reason for this type of question is when a container or custom control type attempts to access properties initialized outside of a custom class where those properties have not yet been initialized thus potentially causing null values to populate and can even cause a null reference exceptions on object types. It means your class is running before it is fully initialized - before you have finished setting your properties etc. Another possible reason for this type of question is when to perform custom graphics.
To best answer the question about when to start executing code following the form load event is to monitor the WM_Paint message or hook directly in to the paint event itself. Why? The paint event only fires when all modules have fully loaded with respect to your form load event. Note: This.visible == true is not always true when it is set true so it is not used at all for this purpose except to hide a form.
The following is a complete example of how to start executing you code following the form load event. It is recommended that you do not unnecessarily tie up the paint message loop so we'll create an event that will start executing your code outside that loop.
using System.Windows.Forms;
namespace MyProgramStartingPlaceExample
{
/// <summary>
/// Main UI form object
/// </summary>
public class Form1 : Form
{
/// <summary>
/// Main form load event handler
/// </summary>
public Form1()
{
// Initialize ONLY. Setup your controls and form parameters here. Custom controls should wait for "FormReady" before starting up too.
this.Text = "My Program title before form loaded";
// Size need to see text. lol
this.Width = 420;
// Setup the sub or fucntion that will handle your "start up" routine
this.StartUpEvent += StartUPRoutine;
// Optional: Custom control simulation startup sequence:
// Define your class or control in variable. ie. var MyControlClass new CustomControl;
// Setup your parameters only. ie. CustomControl.size = new size(420, 966); Do not validate during initialization wait until "FormReady" is set to avoid possible null values etc.
// Inside your control or class have a property and assign it as bool FormReady - do not validate anything until it is true and you'll be good!
}
/// <summary>
/// The main entry point for the application which sets security permissions when set.
/// </summary>
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
#region "WM_Paint event hooking with StartUpEvent"
//
// Create a delegate for our "StartUpEvent"
public delegate void StartUpHandler();
//
// Create our event handle "StartUpEvent"
public event StartUpHandler StartUpEvent;
//
// Our FormReady will only be set once just he way we intendded
// Since it is a global variable we can poll it else where as well to determine if we should begin code execution !!
bool FormReady;
//
// The WM_Paint message handler: Used mostly to paint nice things to controls and screen
protected override void OnPaint(PaintEventArgs e)
{
// Check if Form is ready for our code ?
if (FormReady == false) // Place a break point here to see the initialized version of the title on the form window
{
// We only want this to occur once for our purpose here.
FormReady = true;
//
// Fire the start up event which then will call our "StartUPRoutine" below.
StartUpEvent();
}
//
// Always call base methods unless overriding the entire fucntion
base.OnPaint(e);
}
#endregion
#region "Your StartUp event Entry point"
//
// Begin executuing your code here to validate properties etc. and to run your program. Enjoy!
// Entry point is just following the very first WM_Paint message - an ideal starting place following form load
void StartUPRoutine()
{
// Replace the initialized text with the following
this.Text = "Your Code has executed after the form's load event";
//
// Anyway this is the momment when the form is fully loaded and ready to go - you can also use these methods for your classes to synchronize excecution using easy modifications yet here is a good starting point.
// Option: Set FormReady to your controls manulaly ie. CustomControl.FormReady = true; or subscribe to the StartUpEvent event inside your class and use that as your entry point for validating and unleashing its code.
//
// Many options: The rest is up to you!
}
#endregion
}
}
I know this is an old post. But here is how I have done it:
public Form1(string myFile)
{
InitializeComponent();
this.Show();
if (myFile != null)
{
OpenFile(myFile);
}
}
private void OpenFile(string myFile = null)
{
MessageBox.Show(myFile);
}
You can close your form after some execution..
//YourForm.ActiveForm.Close();
LoadingForm.ActiveForm.Close();
Edit: For clarification, this is in Unity, and is tied to Update(). So the events will be triggered once per frame for any number of frames. Both events can be triggered independently by the user, but there is an overlap in which both can be triggered. In this case I only want one of the two methods that will be called by the two events to actually run.
I'm trying to make a method that is called by one event and other method that is called by a 2nd event be linked in a way that only one of those two methods can be called or ran at the same time.
The events are triggered by an action of the user, both events can be triggered at the same time. But I only want one of the two methods that would be called to actually run if both events are triggered.
I was thinking something along the like of the following example, obviously the example may not be accurate, but the gist of what I am trying to accomplish is there.
Pseudo Code Example:
public delegate void OneHandler();
public event OneHandler OneEvent;
private void One()
{
if(some requirement && TEvent != null)
{
TEvent();
}
}
public delegate void TwoHandler();
public event TwoHandler TwoEvent;
private void Two()
{
if(some requirement && TEvent != null)
{
TEvent();
}
}
SomeClass.OneEvent += ActionOne();
SomeClass.TwoEvent += ActionTwo();
private void ActionOne()
{
if(TwoEvent is not firing)
{
Do Something;
}
}
private void ActionTwo()
{
if(OneEvent is not firing)
{
Do Something;
}
}
A crude diagram. The tan area moves down/left, the green areas move diagonally. I essentially want the tan area which have their own events, to not run their methods if the mouse is within that entire area.
Events fire one at a time, not all at once. Even if the same user action was going to cause both events to fire one after the other, there is no way to know that both events will fire, or in what order they will fire.
To be more clear: I didn't mean events can never be fired concurrently. I mean that, in general, there is no piece of code that determines, for a particular situation, the complete set of events which will be fired. You can't tell ahead of time which will fire, or in which order, or even on which threads.
For example, a particular user interface action (or user gesture) might cause several events to fire. In general, you can't depend on the number of events to be fired, or the order in which they will be fired.
There are some situations, like in ASP.NET web forms, where you can be assured that if the user clicks a button which has a Click event handler, that the page Load event will fire and then that the button Click event will fire. But this is because this behavior is defined and documented that way. If the order changed, or if, for instance, the page Load event stopped firing, then this would break a large number of ASP.NET web forms applications.
If all you're trying to do is guarantee that concurrent triggering (like two threads running on different cores) will never be allowed, you'll want to use something like a mutex. You would have both handlers perform a WaitOne(0) to see if the other handler is working, returning immediately if the call returns false (since the other method must be executing) then in a guaranteed-execution block (such as a finally) you would release the mutex.
How about use bool variable as flag ?
private bool flag[2] = [false, false];
private void ActionOne()
{
flag[0] = true;
if(!(flag[0])&&flag[1]))
{
Do Something;
}
flag[0] = false;
}
private void ActionTwo()
{
flag[1] = true;
if(!(flag[0] && flag[1]))
{
Do Something;
}
flag[1] = false;
}
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.
Using Visual Studio 2012 ulti, C# .NET WPF.
Using Tasks in my code on winforms used to be simple.
All I would do is create a delegate, create a function for my code, create a task and the event would be a simple button. Easy stuff. Problem I have is the following...
Create a thread as per-usual But the event will be on text changed.
The problem im having is thinking about the logic, if I simply change the event I cant see this working as the user could type faster than the code could run ( in this case an sql query select statement). There for it would try to run many tasks which I don't even think would work.
Basically User enters text box that used for searching an account by name or number.
In this textbox I would like to thread the entire process.
The only solution I can think of is as the text changes if there is a thread still running stop that thread and create the new one, but not sure if thats a clean way of doing it as its a sql stored procedure ill be calling.
So any body got a solution to this?
If you need any more info just ask. Ill also provide some code that currently works to give you an understanding if needed...
Set Invoke method up:
private void SetDataGrid(bool AutoGenerateColumns, Object DataSource, String DataMember, DataGridViewAutoSizeColumnsMode Mode)
{
if (this.ParetoGrid.InvokeRequired)
{
this.ParetoGrid.Invoke(new Action<bool, Object, String, DataGridViewAutoSizeColumnsMode>(SetDataGrid),
AutoGenerateColumns, DataSource, DataMember, Mode);
}
else
{
this.ParetoGrid.AutoGenerateColumns = AutoGenerateColumns;
this.ParetoGrid.DataSource = DataSource;
this.ParetoGrid.DataMember = DataMember;
ParetoGrid.AutoResizeColumns(Mode);
}
}
Call invoke method in another method:
Private void GetSomething()
{
//sql code get data
SetDataGrid(true, dataSet1, "Pareto", DataGridViewAutoSizeColumnsMode.AllCells);
}
Then simply start task on event:
private void myButton_Click(Object sender, EventArgs e)
{
Task t = new Task(() => getSomething());
t.Start();
}
As you can see simple stuff, but simple changing event seems to mess the whole logic up.
I'd recomend moving this logic from the task into a Timer callback, then have your OnTextChanged handler actually reset the timer each time it's fired (only have the timer fire once of course). By making the timer elapse after .5-1 sec, or something like that, you'll wait until all of their text has been entered before actually calling your logic. But the user's experience will still be quite responsive.
Example:
private System.Threading.Timer keyEntryTimer = new Timer(Logic,null,-1,-1);
public void HandleEvent(objet sender, EventArgs args)
{
keyEntryTimer.Change(500,-1);
}
public void Logic(objet state)
{
//Your task logic would go here to read from the text etc...
//You'll have to handle any UI updates either by firing off a task once the DB results return or using a dispatcher
}
You can simply cache all accounts when they enter this search mode. Then you can search through cached accounts when they enter text into the textbox. Doing a query in a different thread for every keypress is very heavy on the app.
I would probably do a combination of the other suggested answers and try to delay the firing of the SQL statement using a timer or some similar method, but if the user delayed long enough for the SQL to fire then try to just filter the returned results from that point forward (only if the search string is becoming more restrictive obviously). This could save you expensive SQL round trips and give you a working cache after the first hit (which should be smaller than if you tried to cache everything).
Hope this helps.
I'm working on a Windows Service that where I am attempting to use Parallel.ForEach to spawn unique timed threads. The problem is that if I leave the code alone for several hours in VS or if I stop the service for a few hours and start anything back up - the initial start up code executes twice. Here is a snippet from the static void that the service's OnStart is calling.
Parallel.ForEach(urls, url =>
{
PageGrabber pagegrab = new PageGrabber(url);
if (url.Type.ToLower() == "http")
{
pagegrab.Elapsed += (obj, e) =>
{
pagegrab.CheckNormal();
};
pagegrab.CheckNormal();
}
else
{
pagegrab.Elapsed += (obj, e) =>
{
pagegrab.CheckXML();
};
pagegrab.CheckXML();
}
}
);
This works great if I use Threads directly, but really wanted to update this code a bit. The duplicate execution happens immediately. The PageGrabber object is pretty simple in that it simply uses a WebClient to download either HTML or XML as a string - pretty boring.
I think the problem is that you've subscribed to the Elapsed event by pageGrabber.Elapsed +=...
It is possible for that event to be raised or not.
So in some conditions if the event raised, your method will be called twice, otherwise it will be called once.
I don't think that you could resolve this problem by changing the parallel implementation (using task array instead of Parallel.Foreach). It just might cause the problem occur less often, which is a very bad symptom in parallel programming. You shouldn't let the problems to fade out by making their preconditions of happening harder! You should totally remove them!
So mehrandvd was on the right path. When creating an instance of my class, that used a System.Timers.Timer, it was firing the Elapsed event immediately because the Interval property wasn't being set correctly. Thus:
pagegrab.Elapsed += (obj, e) =>
{
pagegrab.CheckXML();
};
pagegrab.CheckXML();
Caused duplicate execution when nothing had happened in a while because the instance of the class that had the Interval set correctly was no longer in memory. My stupidity - all fixed now. Thanks for all the comments and suggestions.