C# zdarzenia i wątki

0

Cześć, mam sobie wątek, który w pewnym momencie wywołuje zdarzenie. Zdarzenie ma być obsłużone przez główną formę.

Wątek:


//deklaracje
public delegate void DelMyEvent(object Sender, string sname);
public event DelMyEvent MyEvent;

//a w metodzie wątku w pewnym momencie:

if (MyEvent != null) MyEvent(this, sname);

Obsługa jest na formie głównej:


rThread = new MyThread();
rThread.MyEvent +=new MyThread.DelMyEvent(EventFired);

private void EventFired(object sender, string sname)
{
    listBox.Items.Add(sname);
}

No i przy listBox.Items.Add dostaję błąd: InvalidOperationException z komunikatem: "Nieprawidłowa operacja między wątkami: do formantu 'listBox' uzyskiwany jest dostęp z wątku innego niż wątek, w którym został utworzony."

Szukam już z godzinę, ale za bardzo nie wiem, co mam zrobić, żeby było dobrze. Wszędzie tylko piszą o Invoke i o wywołaniu listBox z wątku. A ja chcę z wątku wywołać zdarzenie tylko. Jak to zrobić, żeby było dobrze?

0

Słowa kluczowe InvokeRequired i Invoke ;). Inaczej się nie da. Zdarzenie jest obsługiwane w tym samym wątku, w którym jest wywoływane. Twój kod natomiast odwołuje się w obsłudze zdarzenia do kontrolki na formatce, która jest w innym wątku.

0
Sarrus napisał(a)

Słowa kluczowe InvokeRequired i Invoke ;). Inaczej się nie da. Zdarzenie jest obsługiwane w tym samym wątku, w którym jest wywoływane. Twój kod natomiast odwołuje się w obsłudze zdarzenia do kontrolki na formatce, która jest w innym wątku.

Ale to jak ja to mam zrobić? No bo ja nie wiem, co będzie w ciele obsługi zdarzenia. Nie mogę się z wątku odwołać bezpośrednio do żadnego obiektu, mogę jedynie wywołać zdarzenie.

Dokładnie to ja chcę, żeby w ciele obsługi zdarzenia już działała forma, a nie wątek.

0
delegate void EventFiredDelegate(object sender, string sname);
private void EventFired(object sender, string sname)
{
    if (InvokeRequired)
      {
          Invoke(new EventFiredDelegate(EventFired), sender, sname);
          return;
      }
    listBox.Items.Add(sname);
}

Istnieje też sposób wykorzystujący klasę AsyncOperation i jej metodę Post, ale w tym wypadku z Invoke jest chyba prościej.

0
Fr33Q napisał(a)
delegate void EventFiredDelegate(object sender, string sname);
private void EventFired(object sender, string sname)
{
if (InvokeRequired)
{
Invoke(new EventFiredDelegate(EventFired), sender, sname);
return;
}
listBox.Items.Add(sname);
}

Istnieje też sposób wykorzystujący klasę AsyncOperation i jej metodę Post, ale w tym wypadku z Invoke jest chyba prościej.

OK, dzięki wielkie, to działa. Rozumiem, że po bloku IF steruje już główna forma, tak?

0

Nie to po bloku if wykonuje się wtedy, gdy zdarzenie będzie wywołane z tego samego wątku co jest formatka

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0