Vincent Dagpin
Vincent Dagpin

Reputation: 3611

C# Event without Invoke

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

Answers (5)

Mark Hall
Mark Hall

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

Francis
Francis

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

dlev
dlev

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

Yuck
Yuck

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

Tesserex
Tesserex

Reputation: 17314

No, Timers 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

Related Questions