Reputation: 3611
im new to C# Event and i want to fire an event without getting a Cross-Thread error..
using System;
using System.Timers;
public class SampleTickEvent
{
private string passStr = string.Empty;
Timer t = new Timer(1000);
public delegate void ImageEventHandler(string s);
public event ImageEventHandler ImageEventTrigger;
public void Start(string ss)
{
passStr = ss;
t.Start();
t.Elapsed += t_Elapsed;
}
public void t_Elapsed(object sender, ElapsedEventArgs eea)
{
ImageEventTrigger(passStr);
}
}
private void button1_Click(object sender, EventArgs e)
{
SampleTickEvent ste = new SampleTickEvent();
ste.Start("sample");
ste.ImageEventTrigger += ste_ImageEventTrigger;
}
private void ste_ImageEventTrigger(string s)
{
Action act = () => listBox1.Items.Add(s);
Invoke(act);
}
is there another way that i will not put the Action act = () = ... and put listbox1.Items.Add(s) instead?
Upvotes: 1
Views: 348
Reputation: 54562
Try using the System.Windows.Forms.Timer
instead of System.Timers.Timer
.
From above Msdn Link:
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.
Upvotes: 1
Reputation: 3383
If you're in Windows Forms, you can use System.Windows.Forms.Timer instead of System.Timers.Timer. The tick event executes in the UI Thread : http://netpl.blogspot.com/2010/05/systemwindowsformstimer-vs.html
Upvotes: 2
Reputation: 48606
Rather than using System.Timers.Timer
, trying using System.Windows.Forms.Timer
, which is written so that it raises the event on the UI thread.
Upvotes: 3
Reputation: 50865
You could change this option during application startup:
System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false;
This would go in whichever Form
you're using as the main application thread.
Upvotes: 1
Reputation: 17314
No, Timer
s operate on a thread from the thread pool, and so to safely modify your form controls, you need to use Invoke
.
You could inline the action, but that's about it.
If you want to put the Invoke
into the SampleTickEvent.t_Elapsed
method, then you'll have to pass a Control
as a handle into the SampleTickEvent
first. Or, you could just create a new Control
as a member of the the SampleTickEvent
in its constructor, and call Invoke
on that. I've done it that way before.
Upvotes: 1