Событие C # без Invoke - PullRequest
       1

Событие C # без Invoke

1 голос
/ 18 ноября 2011

я новичок в C # Event, и я хочу запустить событие, не получая ошибку Cross-Thread.

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);
    }

есть еще один способ, которым я не буду помещать действиеact = () = ... и поставить вместо него listbox1.Items.Addms (s)?

Ответы [ 5 ]

3 голосов
/ 18 ноября 2011

Вместо использования System.Timers.Timer, попробуйте использовать System.Windows.Forms.Timer, который написан так, что вызывает событие в потоке пользовательского интерфейса.

2 голосов
/ 18 ноября 2011

Если вы работаете в Windows Forms, вы можете использовать System.Windows.Forms.Timer вместо System.Timers.Timer.Событие галочки выполняется в потоке пользовательского интерфейса: http://netpl.blogspot.com/2010/05/systemwindowsformstimer-vs.html

1 голос
/ 18 ноября 2011

Попробуйте использовать System.Windows.Forms.Timer вместо System.Timers.Timer.

Сверху Msdn Link:

Этот таймер Windows предназначен для однократногомногопоточная среда, в которой потоки пользовательского интерфейса используются для выполнения обработки.Требуется, чтобы в коде пользователя был доступен насос сообщений интерфейса пользователя, и он всегда работал из одного потока, или перенаправил вызов в другой поток.

1 голос
/ 18 ноября 2011

Вы можете изменить эту опцию при запуске приложения:

System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false;

Это будет указывать Form, который вы используете в качестве основного потока приложения.

1 голос
/ 18 ноября 2011

Нет, Timer s работают с потоком из пула потоков, поэтому для безопасного изменения элементов управления формы вам необходимо использовать Invoke.

Вы можете встроить действие, но это примерноit.

Если вы хотите поместить Invoke в метод SampleTickEvent.t_Elapsed, тогда вам нужно будет передать Control в качестве дескриптора в SampleTickEvent первым.Или вы можете просто создать новый Control в качестве члена SampleTickEvent в его конструкторе и вызвать Invoke для этого.Я делал это раньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...