Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Wednesday, September 16, 2009 2:48 PM
I have a couple of timers in my form. They work fine and do a good job. Now I decided to add another one. I invoke it reflectively from another class (not Windows.Forms.Form class) and I demonstqared that the routine that is supposed to trigger the timer is in fact invoked. The Tick event is consistently silent though. Why? What am I missing?
public void startTimerTemp ( )
{
Console.WriteLine ( "We are in timerTemp" ); // I see this in Console.
timerTemp.Interval = 300;
timerTemp.Tick += new EventHandler ( timerTemp_Tick );
timerTemp.Tag = "0";
timerTemp.Enabled = true;
timerTemp.Start ( );
} // startTimerTemp
private void timerTemp_Tick ( object sender, EventArgs ee )
{
Console.WriteLine ( "We are in timerTemp_Tick" ); // This I don't see at all
Timer timer = ( Timer )sender;
string arg = ( string )timer.Tag; // counter
int counter = int.Parse ( arg );
counter++;
timer.Tag = counter;
axil.writeLogFile ( "IntNote", "timerTemp_Tick: sending RefreshTransaction request" ); // neither this in the log file.
// Actual work
if ( counter > 5 )
{
timerTemp.Enabled = false;
timer.Stop ( );
}
} // timerTemp_Tick
Thanks.
AlexB
All replies (50)
Wednesday, September 16, 2009 3:01 PM
Is the timer actually placed on the form in the designer?
-SteveProgramming blog: http://nitoprograms.blogspot.com/
Including my TCP/IP .NET Sockets FAQ
MSBuild user? Try out the DynamicExecute task in the MSBuild Extension Pack source; it's currently in Beta so get your comments in!
Wednesday, September 16, 2009 3:29 PM
Is the timer actually placed on the form in the designer?
-Steve
Programming blog: http://nitoprograms.blogspot.com/
Including my TCP/IP .NET Sockets FAQ
MSBuild user? Try out the DynamicExecute task in the MSBuild Extension Pack source; it's currently in Beta so get your comments in!
No, it is not. Do you think I should do it? OK, I jsut checked. This could be a problem. Other timers are properly define din the consructor and attached to component. They all been dropped.
Thanks, Steve.
AlexB
Wednesday, September 16, 2009 3:37 PM
Steve, it has not changed anything, sorry. It still does not fire and conceptually it does not seem to have anything to do with the proble, the wasy you define a timer. I did define it properly.
AlexB
Wednesday, September 16, 2009 3:43 PM
This is how it is define dnow after I dropped it instead of defining it in a simple way:
this.timerTemp = new System.Windows.Forms.Timer ( this.components );
( ( System.ComponentModel.ISupportInitialize )( this.bindingSource1 ) ).BeginInit ( );
( ( System.ComponentModel.ISupportInitialize )( this.bindingSource4 ) ).BeginInit ( );
( ( System.ComponentModel.ISupportInitialize )( this.bindingSource2 ) ).BeginInit ( );
( ( System.ComponentModel.ISupportInitialize )( this.bindingSource3 ) ).BeginInit ( );
The four binding sources are apparently related to four timers now defined. I do have one that seems to be unused and I may switch to that but I want to find out the cause of this malfunction sinee it can repeat itself again elsewhere.AlexB
Wednesday, September 16, 2009 3:49 PM
I just replaced this timer with the unused one and still no firing.AlexB
Wednesday, September 16, 2009 4:05 PM
Guys I need an asnwer, please help with your suggestions.AlexB
Wednesday, September 16, 2009 4:12 PM
Alex, you need to call Application.DoEvents() in order for your Timer to fire.
class Program
{
static void Main(string[] args)
{
TimerTest test = new TimerTest();
while (true)
{
System.Windows.Forms.Application.DoEvents();
}
}
}
public class TimerTest
{
System.Windows.Forms.Timer timerTemp = new System.Windows.Forms.Timer();
public TimerTest()
{
startTimerTemp();
}
public void startTimerTemp()
{
Console.WriteLine("We are in timerTemp"); // I see this in Console.
timerTemp.Interval = 300;
timerTemp.Tick += new EventHandler(timerTemp_Tick);
timerTemp.Tag = "0";
//timerTemp.Enabled = true;
timerTemp.Start();
} // startTimerTemp
private void timerTemp_Tick(object sender, EventArgs ee)
{
Console.WriteLine("We are in timerTemp_Tick"); // This I don't see at all
System.Windows.Forms.Timer timer = (System.Windows.Forms.Timer)sender;
string arg = timer.Tag.ToString(); // counter (CHANGED THIS TO .TOSTRING!)
int counter = int.Parse(arg);
counter++;
timer.Tag = counter;
// Actual work
if (counter > 5)
{
timerTemp.Enabled = false;
timer.Stop();
}
}
}
おろ?
Wednesday, September 16, 2009 4:15 PM
Also, make the counter a field of the TimerTest class so it doesn't reset:
public class TimerTest
{
int counter = 0;
counter = int.Parse(arg);
おろ?
Wednesday, September 16, 2009 4:41 PM
Brian, thanks for suggestion. I will try it and if it works I will mark your post as "answer." However I have doubts. My other three timers do not use it but they seem to work, actually two of them. I don't have it in my application, I mean this statement. Also I recall vaguely that there was a blog which recommended not to use it at all. I don't recall the reason.
Thanks.AlexB
Wednesday, September 16, 2009 4:51 PM
The problem is based on the System.Windows.Forms.Timer class itself. It is not designed for multithreading and puts its calls in the windows message queue. If you want to avoid using DoEvents you can switch to System.Timers.Timer. It is highly detailed in an msdn article.
おろ?
Wednesday, September 16, 2009 5:29 PM
Show the code that calls startTimerTemp. Is timerTemp_Tick common to all the timers? Why do you set the Tag to a string, cast it to a string, cast the string to an int, set the Tag to an int, cast it to a string, cast the string to an int and so on? Why not just set the Tag to an int?
Wednesday, September 16, 2009 5:42 PM
Right-O...
I did assume that the timer is a System.Windows.Forms.Timer, and that it is being used in a Windows Forms application (hence, the Application.Run will call DoEvents for you). It's multithreaded in the same sense that any other Windows control is multithreaded - it can only be used from its creating GUI thread.
It should have its own window handle, so technically it doesn't need to be on a form. It does need to be only accessed from a GUI thread, though.
-SteveProgramming blog: http://nitoprograms.blogspot.com/
Including my TCP/IP .NET Sockets FAQ
MSBuild user? Try out the DynamicExecute task in the MSBuild Extension Pack source; it's currently in Beta so get your comments in!
Wednesday, September 16, 2009 5:49 PM
Right-O...
I did assume that the timer is a System.Windows.Forms.Timer, and that it is being used in a Windows Forms application (hence, the Application.Run will call DoEvents for you). It's multithreaded in the same sense that any other Windows control is multithreaded - it can only be used from its creating GUI thread.
It should have its own window handle, so technically it doesn't need to be on a form. It does need to be only accessed from a GUI thread, though.
-Steve
Programming blog: http://nitoprograms.blogspot.com/
Including my TCP/IP .NET Sockets FAQ
MSBuild user? Try out the DynamicExecute task in the MSBuild Extension Pack source; it's currently in Beta so get your comments in!
If I understood that article properly, yes it is true that the UI will check messages, but only "During idle time". Which should help explain why Alex see's the same timer class working sometimes, but not in all cases (particularly this one).おろ?
Wednesday, September 16, 2009 5:58 PM
Idle time should account for the majority of time in a GUI thread. Other threads may be given long-running tasks to do, but a GUI thread should mainly be responsible for updating its GUI and its "GUI state" (e.g., View and ViewModel classes if you're doing MVVM).
This is the central concept around which Win32 was designed.
Calling DoEvents is usually a sign that the above advice has been ignored. DoEvents brings its own bag of problems to the table, particularly regarding reentrancy. It is best avoided.
The fact that his existing timers work but this one doesn't seems to indicate a code problem, not a timing problem. That's my guess...
-SteveProgramming blog: http://nitoprograms.blogspot.com/
Including my TCP/IP .NET Sockets FAQ
MSBuild user? Try out the DynamicExecute task in the MSBuild Extension Pack source; it's currently in Beta so get your comments in!
Wednesday, September 16, 2009 6:50 PM
I did assume that the timer is a System.Windows.Forms.Timer,
That's correct. After all I then dropped it on the form. I cannot from the Threading namespace.AlexB
Wednesday, September 16, 2009 6:56 PM
Show the code that calls startTimerTemp. Is timerTemp_Tick common to all the timers? Why do you set the Tag to a string, cast it to a string, cast the string to an int, set the Tag to an int, cast it to a string, cast the string to an int and so on? Why not just set the Tag to an int?
John, I will show you the code but I told you that routine works for certain. Heer we go:
public class Form1MethodInvoke
{
[PermissionSetAttribute ( SecurityAction.Demand, Name = "FullTrust" )]
public void startMethodInfo ( )
{
MethodInfo mi1 = typeof ( Form1 ).GetMethod ( "startTimerTemp", BindingFlags.Public | BindingFlags.Instance |
BindingFlags.InvokeMethod );
Form1 form1 = new Form1 ( );
mi1.Invoke ( form1, null );
} // startMethodInfo
} // class Form1MethodInvoke
Then somewhere in the code:
Form1MethodInvoke invoke = new Form1MethodInvoke ( );
invoke.startMethodInfo ( );
No, the timerTemp_Tick is individual. Each timer has its individual event handler.
And again, i am saying that this code works and the routine startTimerTemp fires. I can see Console output. Steve, I posted all the code, what else could it be?
Thanks.
AlexB
Wednesday, September 16, 2009 7:01 PM
The problem is based on the System.Windows.Forms.Timer class itself. It is not designed for multithreading and puts its calls in the windows message queue. If you want to avoid using DoEvents you can switch to System.Timers.Timer. It is highly detailed in an msdn article.
おろ?
This is a great article. Thanks.AlexB
Wednesday, September 16, 2009 7:05 PM
Steve, I marked your very informative post as "answer." as a downpayment for your final resolution of the problem:) I am sure you will be able to crack it. I used to have a suspicion from years past that only limited number of Windows.Forms.Timer instances are allowed in an application.
AlexB
Wednesday, September 16, 2009 7:32 PM
There is a limit to Windows timers, but it's very high. You shouldn't hit it unless you're leaking them.
Make sure that the thread using Form1MethodInvoke does eventually enter a message loop (Application.Run).
-SteveProgramming blog: http://nitoprograms.blogspot.com/
Including my TCP/IP .NET Sockets FAQ
MSBuild user? Try out the DynamicExecute task in the MSBuild Extension Pack source; it's currently in Beta so get your comments in!
Wednesday, September 16, 2009 8:33 PM
This timer never fires and the other timers with shorter intervals continue to fire during this timer's interval? If so, then check that this timer is enabled in one of the other timer's tick event. Set a boolean telling it to do so in a statement following the Console.WriteLine statement. You're using Invoke, which is a synchronous blocking call. Try calling it asynchronously using BeginInvoke and EndInvoke.
Wednesday, September 16, 2009 8:49 PM
This timer never fires and the other timers with shorter intervals continue to fire during this timer's interval? If so, then check that this timer is enabled in one of the other timer's tick event. Set a boolean telling it to do so in a statement following the Console.WriteLine statement. You're using Invoke, which is a synchronous blocking call. Try calling it asynchronously using BeginInvoke and EndInvoke.
The other timers have longer Intervals: 5 seconds and 10.What would BegnInvoke do as compared with th synchornous call. Do you think it is a problem? I get the initial routine invoked no problem at all. The timer does not start.
MethodInfo mi1 = typeof ( Form1 ).GetMethod ( "startTimerTemp", BindingFlags.Public | BindingFlags.Instance |
BindingFlags.InvokeMethod );
Form1 form1 = new Form1 ( );
**mi1.Invoke ( form1, null );
**
The line I highlighted works.
However, in major Form1 class:
public void startTimerTemp ( )
{
Console.WriteLine ( "We are in timerTemp" ); // **<== I see this in Console.
** timerTemp.Interval = 300;
timerTemp.Tick += new EventHandler ( timerTemp_Tick );
timerTemp.Tag = "0";
timerTemp.Enabled = true;
** timerTemp.Start ( ); // This does not work at all.
** } // startTimerTemp
private void timerTemp_Tick ( object sender, EventArgs ee )
{
Console.WriteLine ( "We are in timerTemp_Tick" ); // This I don't see at all
AlexB
Wednesday, September 16, 2009 8:58 PM
John, I don't think your asynchronous argument is valid here since I always get the first routine fired.AlexB
Wednesday, September 16, 2009 9:12 PM
I thought the timer still wasn't firing. I guess I misread the posts. Since you've marked the thread as answered, I guess you're problem is solved. I just didn't comprehend that from the posts.
Wednesday, September 16, 2009 9:22 PM
No it is not solved. I often mark post as "answer" when people give me any useful suggestions. I am very generous:) Maybe I should b more careful with this. I will rather unmark all my "answers" and remark later.
AlexB
Wednesday, September 16, 2009 9:49 PM
This timer never fires and the other timers with shorter intervals continue to fire during this timer's interval? If so, then check that this timer is enabled in one of the other timer's tick event. Set a boolean telling it to do so in a statement following the Console.WriteLine statement. You're using Invoke, which is a synchronous blocking call. Try calling it asynchronously using BeginInvoke and EndInvoke.
The other timers have longer Intervals: 5 seconds and 10.What would BegnInvoke do as compared with th synchornous call. Do you think it is a problem? I get the initial routine invoked no problem at all. The timer does not start.
MethodInfo mi1 = typeof ( Form1 ).GetMethod ( "startTimerTemp", BindingFlags.Public | BindingFlags.Instance |
BindingFlags.InvokeMethod );
Form1 form1 = new Form1 ( );
**mi1.Invoke ( form1, null );
**The line I highlighted works.
public void startTimerTemp ( )
{
Console.WriteLine ( "We are in timerTemp" ); // **<== I see this in Console.
** timerTemp.Interval = 300;
timerTemp.Tick += new EventHandler ( timerTemp_Tick );
timerTemp.Tag = "0";
timerTemp.Enabled = true;
** timerTemp.Start ( ); // This does not work at all.
** } // startTimerTempprivate void timerTemp_Tick ( object sender, EventArgs ee )
{
Console.WriteLine ( "We are in timerTemp_Tick" ); // This I don't see at all
**"timerTemp.Start ( ); // This does not work at all."
**
I bet it does. Add this line after it:
Console.WriteLine ( "We are at the end of timerTemp" );
And if it does, you're blocking the UI thread.
Wednesday, September 16, 2009 9:56 PM
And if it does, you're blocking the UI thread.
I accept you insight but what can I do about it? To use InvokeRequired on it? I like it, it won't take a lot of time to try. We'll see.
AlexB
Wednesday, September 16, 2009 10:04 PM
No john, it is not going to work. System.Windows.Forms.Timer does not have BeginInvoke. It does not have IsHandleCreated property either.
AlexB
Wednesday, September 16, 2009 10:05 PM
And if it does, you're blocking the UI thread.
I accept you insight but what can I do about it? To use InvokeRequired on it? I like it, it won't take a lot of time to try. We'll see.
AlexB
That's not going to do it. You're going to have to make an asynchronous call.
Wednesday, September 16, 2009 10:07 PM
I need this timer badly:)AlexB
Wednesday, September 16, 2009 10:07 PM
And if it does, you're blocking the UI thread.
I accept you insight but what can I do about it? To use InvokeRequired on it? I like it, it won't take a lot of time to try. We'll see.
AlexB
That's not going to do it. You're going to have to make an asynchronous call.
But again why? The first routine does work.AlexB
Wednesday, September 16, 2009 10:15 PM
No john, it is not going to work. System.Windows.Forms.Control does not have BeginInvoke. It does not have IsHandleCreated property either.
AlexB
Timers are not controls. Start it in Form.BeginInvoke.
Wednesday, September 16, 2009 10:17 PM
Alex, is your timer running on the MainUI thread? If the answer is no, then the timer is not following the design guidelines under which it was created. Since we already know your application is multi-threaded I still firmly suggest that you switch timers. Here's a snippet from the MSDN regarding System.Windows.Forms.Timer.
"The Windows Forms Timer component is single-threaded, and is limited to an accuracy of 55 milliseconds. If you require a multithreaded timer with greater accuracy, use the Timer class in the System.Timers namespace."
And in the same article...
"This Windows timer is designed for a single-threaded environment where UI threads are used to perform processing. It requires that the user code have a UI message pump available and always operate from the same thread, or marshal the call onto another thread. "
おろ?
Thursday, September 17, 2009 6:00 AM
The synchronous call in the following code reproduces your result
public Form1()
{
InitializeComponent();
tmr.Tick += tmr_Tick;
bgw.DoWork += bgw_DoWork;
bgw.WorkerReportsProgress = true;
bgw.DoWork += bgw_DoWork;
bgw.ProgressChanged += bgw_ProgressChanged;
}
Timer tmr = new Timer();
BackgroundWorker bgw = new BackgroundWorker();
Stopwatch sw = new Stopwatch();
private void button1_Click(object sender, EventArgs e)
{
sw.Start();
bgw.RunWorkerAsync();
}
void StartTimer1(string method)
{
Console.WriteLine(sw.ElapsedMilliseconds.ToString() + " startTmr " + method);
tmr.Start();
}
private void tmr_Tick(object sender, EventArgs e)
{
tmr.Stop();
Console.WriteLine(sw.ElapsedMilliseconds.ToString() +" tmr started");
tmr.Tag = "";
}
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
tmr.Tag = "Async";
bgw.ReportProgress(0);
while ((string)tmr.Tag == "Async") System.Threading.Thread.Sleep(10);
tmr.Tag = "Sync";
StartTimer1("Sync");
while ((string)tmr.Tag == "Sync") System.Threading.Thread.Sleep(10);
}
private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
StartTimer1("Async");
}
Thursday, September 17, 2009 10:49 AM
Assuming that you are accessing the timer only from a GUI thread (which is necessary since it has thread affinity), and your GUI thread does actually have a message loop (e.g., Run), then the problem is probably that your GUI thread is too busy. This wouldn't explain why the other timers work, though.
I'd double-check the above assumptions using trace statements to the debugger (e.g., Debug.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " entering Run()") immediately before Run()), and ensure that the timer is constructed and referenced only from the same thread (right click on timerTemp -> find all references). If you run it in the debugger, those come to the Output window; if running outside the debugger, you can still see them using Systems Internals DbgView.
There isn't anything wrong with calling Invoke on the MethodInfo (other than you're using reflection, but I assume that you have a reason for that); you could use BeginInvoke on a delegate which calls MethodInfo.Invoke, but it wouldn't get you anything in this situation. I think John was thinking about Invoke/BeginInvoke on a Control, which is completely different.
If the timer is indeed always accessed from the GUI thread, and the GUI thread has a message loop, then it may be best to see if you can develop a minimal reproducible test case that can be posted.
-SteveProgramming blog: http://nitoprograms.blogspot.com/
Including my TCP/IP .NET Sockets FAQ
MSBuild user? Try out the DynamicExecute task in the MSBuild Extension Pack source; it's currently in Beta so get your comments in!
Thursday, September 17, 2009 12:23 PM
Thank you Steve, I may try it later today. I am not sure but it seems I am accessing it not from a GUI thread. Every time I try to influence a Form contol from this routine or similar, dealing with input stream and this one does it, I get an Exception and have to use InvokeRequired type routine to check for thread availability. I am wondering if WndProc is an avenue to explore in heer?
I may need to ask you a few questions on the method you described later and also I am not sure if it will work in my high demand environment. That timer is activated not from the start but some time after the stream is already being loaded in the tables. Of course it remains to be seen. I will test it. It may be also a good way to troubleshoot other issues.AlexB
Thursday, September 17, 2009 12:47 PM
Thank you Steve, I may try it later today. I am not sure but it seems I am accessing it not from a GUI thread. Every time I try to influence a Form contol from this routine or similar, dealing with input stream and this one does it, I get an Exception and have to use InvokeRequired type routine to check for thread availability. I am wondering if WndProc is an avenue to explore in heer?
That definitely sounds like you're accessing it from a non-GUI thread. Or possibly more than one kind of thread (I personally dislike any design where a method may be called by different types of threads; I find it complicates things way too quickly, and InvokeRequired is too often used as a patch instead of fixing the design).
-SteveProgramming blog: http://nitoprograms.blogspot.com/
Including my TCP/IP .NET Sockets FAQ
MSBuild user? Try out the DynamicExecute task in the MSBuild Extension Pack source; it's currently in Beta so get your comments in!
Thursday, September 17, 2009 12:52 PM
Steve, what do you think of WndProc to send a message to the GUI thread and activate the timer.
Actually I have another way to do it. I completely forgot. I have a static TextBox in my static class Globals and TextChanged event handler in the GUI Form class and I communicate many messages very successfully and without a single miss thru that. I sort of forgot about it completely. I use it to send messages primarily from some satellite forms and it works great but also from other classes that seem to get instantiated in different threads.
AlexB
Thursday, September 17, 2009 12:53 PM
Could you also try to figure out my freezing problem. It is in a defferent thread. It is of an order of magnitude moer serious.
Thanks.
AlexB
Thursday, September 17, 2009 1:02 PM
Well, using WndProc (I'm interpreting this to mean "send a Windows message") directly isn't necessary. That's exactly what Control.BeginInvoke/Control.Invoke does under the covers.
-SteveProgramming blog: http://nitoprograms.blogspot.com/
Including my TCP/IP .NET Sockets FAQ
MSBuild user? Try out the DynamicExecute task in the MSBuild Extension Pack source; it's currently in Beta so get your comments in!
Thursday, September 17, 2009 5:43 PM
Assuming that you are accessing the timer only from a GUI thread (which is necessary since it has thread affinity), and your GUI thread does actually have a message loop (e.g., Run), then the problem is probably that your GUI thread is too busy. This wouldn't explain why the other timers work, though.
Bad assumption. What he describes is exactly what you get if you start the timer from a non-UI thread. The timer starts and Enabled is true, but it never ticks.
Thursday, September 17, 2009 10:11 PM
John, what the background worker will give me as compared to regular threading? Also it seems in your code the timer is invoked from the GUI thread and this is not what I need.
AlexB
Thursday, September 17, 2009 10:31 PM
John, what the background worker will give me as compared to regular threading? Also it seems in your code the timer is invoked from the GUI thread and this is not what I need.
AlexB
I just used the BackgroundWorker to show the difference between starting the timer on the UI thread and starting it on another thread. I find the BackgroundWorker to be more reliable than most theading implementations. As you have seen, if you don't start the timer on the UI thread, it will never tick. You're reflecting the method, you just need to call it on the UI thread.
Friday, September 18, 2009 3:48 PM
You're reflecting the method, you just need to call it on the UI thread.
That's easier said than done. The process that needs the timer is in another thread. If certain events did occur in there then the server must be notified and that can be done only from the Main thread. A series of requests is sent at periodic intervals and the returns are monitored, I am describing an ideal situation which does not really work as you know. So, I need the timer to send those requests and monitor the results but the client who needs them is on the other side of the .NET so to speak.AlexB
Friday, September 18, 2009 6:31 PM
Alex, here's how you can fire a timer event across thread boundries. I included, but commented out, a single thread implenmentation that you may choose to review for comparison. Buena suerte.
public partial class TimerThread : Form
{
private delegate void ShowTimerEventFiredDelegate(DateTime eventTime, string threadName);
int tickCountMultiThread;
int tickCountSingleThread;
System.Threading.Thread t1;
public TimerThread()
{
tickCountMultiThread = 0;
tickCountSingleThread = 0;
InitializeComponent();
//ThisThreadTimer();
StartThread();
}
//private void ThisThreadTimer()
//{
// System.Timers.Timer tmrTimersTimer = new System.Timers.Timer();
// tmrTimersTimer.Interval = 1000;
// tmrTimersTimer.Elapsed += new ElapsedEventHandler(tmrTimersTimer_ElapsedSingleThread);
// tmrTimersTimer.SynchronizingObject = this; //Synchronize with the current form...
// tmrTimersTimer.Start();
//}
//private void tmrTimersTimer_ElapsedSingleThread(object sender, System.Timers.ElapsedEventArgs e)
//{
// // Do something on the UI thread (same thread the form was created on)...
// // If we didn't set SynchronizingObject we would be on a worker thread...
// listBox2.TopIndex = listBox2.Items.Add(String.Format("—> Timer Event {0} @ {1} on Thread: {2}", ++tickCountSingleThread, DateTime.Now, "main thread"));
//}
private void ShowTimerEventFired(DateTime eventTime, string threadName)
{
//InvokeRequired will be true when using
//System.Threading.Timer or System.Timers.Timer (without a
//SynchronizationObject)...
if (listBox1.InvokeRequired) {
//Marshal this call back to the UI thread (via the form
//instance)...
BeginInvoke(new
ShowTimerEventFiredDelegate(ShowTimerEventFired),
new object[] {eventTime, threadName});
}
else
listBox1.TopIndex = listBox1.Items.Add(String.Format("—> Timer Event {0} @ {1} on Thread: {2}",++tickCountMultiThread, eventTime.ToLongTimeString(), threadName));
}
private void StartThread()
{
t1 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(StartTimer));
t1.Name = "child thread";
t1.Start();
}
private void StartTimer(Object o)
{
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Interval = 1000;
aTimer.Elapsed += new ElapsedEventHandler(tmrTimersTimer_Elapsed);
aTimer.Start();
}
private void tmrTimersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
ShowTimerEventFired(DateTime.Now, t1.Name);
}
}
おろ?
Friday, September 18, 2009 8:39 PM
Note that the source code above assumes a Form with 2 listboxes named listBox1 and listBox2.おろ?
Sunday, September 20, 2009 12:09 AM
Thank you, Brian, I will try it tomorrow.AlexB
Sunday, September 20, 2009 4:48 PM
Brina, I am trying to disect your code. I like the idea but have some reservations although they may be dispelled when I try it. It is not that immediate for me to incorporate it into my code. The issue here is that you are starting your thread from GUI thread with the timer located in GUI thread, I will have to kick the whole thing from a totaly alien thread with the timer located in the GUI thread. Do you think it will make a difference?AlexB
Sunday, September 20, 2009 8:57 PM
@Alex
"I will have to kick the whole thing from a totaly alien thread with the timer located in the GUI thread."
I think the way the threads communicate needs to be further explored in order to reach a solution. Is the alien thread in the same process as the GUI or are we talking about inter-process communication?
おろ?
Monday, October 5, 2009 6:40 AM
Hi Alex
Have you found a solution now?
Thanks.
Figo Fei
MSDN Subscriber Support in Forum
If you have any feedback on our support, please contact msdnmg[at]microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Monday, October 5, 2009 4:47 PM
Hi Alex
Have you found a solution now?
Thanks.
Figo Fei
MSDN Subscriber Support in Forum
If you have any feedback on our support, please contact msdnmg[at]microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Hi Figo,
No, that configuration never worked. I had to abandone it. I don't quite recall now what substitute I implemented. It seems what I did was to use TextChanged delegate in a static, globally accessible textBox which is only declared as such but there is nothing in the constructor. I carry a lot of messages this way between classes that otherwise are difficult to send.
Thanks.
AlexB