konto usunięte

Temat: Komunikaty do jednego wątku z wielu innych

`Piotr Sowa edytował(a) ten post dnia 12.02.12 o godzinie 15:00
Michał Ziober

Michał Ziober Architekt, Starszy
Programist Java, CEO
w Celoxity

Temat: Komunikaty do jednego wątku z wielu innych

Zawsze możesz użyć delegatów. Poniżej przedstawiam mały przykład:

public delegate void LogHandler(T message);

public class Program
{
private static List log = new List();

[STAThread]
static void Main(string[] args)
{
Worker[] workers = new Worker[10];
for (int i = 0; i < workers.Length; i++)
{
workers[i] = new Worker();
workers[i].Log += new LogHandler(Log);
}
for (int i = 0; i < workers.Length; i++)
workers[i].RunWorkerAsync(i);

while (Array.Find(workers, delegate(Worker worker)
{
return worker.IsBusy;
}) != null)
{
Thread.Sleep(1000);
}
log.ForEach(delegate(String message)
{
Console.WriteLine(message);
});
}

[MethodImpl(MethodImplOptions.Synchronized)]
private static void Log(Object value)
{
log.Add(value.ToString());
}

public class Worker : BackgroundWorker
{
private Random _random = new Random(Environment.TickCount);
public event LogHandler Log;

protected override void OnDoWork(DoWorkEventArgs e)
{
base.OnDoWork(e);
Console.WriteLine("Watek numer: {0} ", e.Argument.ToString());
for(int i = 0; i < 3; i++)
if (Log != null)
{
Thread.Sleep(_random.Next(300, 600));
Log(String.Format("Zdarzenie numer: {0} od {1}", i, e.Argument.ToString()));
}

}
}
}
Krzysztof Mierzejewski

Krzysztof Mierzejewski SharePoint
Consultant

Temat: Komunikaty do jednego wątku z wielu innych

Polecam zapoznać się z wątkiem (tak na przyszłość) Threadsafe events

konto usunięte

Temat: Komunikaty do jednego wątku z wielu innych

`Piotr Sowa edytował(a) ten post dnia 12.02.12 o godzinie 15:00

Temat: Komunikaty do jednego wątku z wielu innych

Offtop: Zanim wyślesz kod z typami generycznymi (a ogólnie z lewym i prawym nawiasem ostrym), zamień je na encje HTML - wówczas przejdzie :)

Zgłosiłem już problem do GL.

konto usunięte

Temat: Komunikaty do jednego wątku z wielu innych

`Piotr Sowa edytował(a) ten post dnia 12.02.12 o godzinie 15:00

konto usunięte

Temat: Komunikaty do jednego wątku z wielu innych

`Piotr Sowa edytował(a) ten post dnia 12.02.12 o godzinie 15:00

konto usunięte

Temat: Komunikaty do jednego wątku z wielu innych

Piotr S.:
Już wiem, Control.BeginInvoke, można zamknąć temat.
Gdybyś napisał, że chodzi Ci o aplikację z GUI i że przez główny wątek rozumiesz po prostu UI thread to miałbyś to szybciej:)

W WPFie masz to na control.Dispatcher.BeginInvoke

Przy okazji: BackgroundWorker jest na tyle inteligentny, że odpala zdarzenia w tym wątku, w którym go stworzono. Jeżeli stworzysz go w wątku UI to mimo, że robotę będzie wykonywał w thread poolu, zdarzenia pojawią się w wątku UI. Ogólnie polecam BackgroundWorker bo:
- jest bardzo wydajny używając thread pool'a
- ma bardzo proste API oparte na zdarzeniach

konto usunięte

Temat: Komunikaty do jednego wątku z wielu innych

`Piotr Sowa edytował(a) ten post dnia 12.02.12 o godzinie 15:01

konto usunięte

Temat: Komunikaty do jednego wątku z wielu innych

Piotr S.:
W jaki sposób wykonywać jedno zadanie BackgroundWorkera wielokrotnie?
Nie wiem i pewno się nie da. Pozostaje więc tworzyć nowe BW za każdym razem co może i jest łatwe ale.... trzeba pamiętać w jakim wątku się go tworzy.

Wobec takiego skomplikowania korzyści z BW maleją i bezpieczniej chyba pozostać przy BeginInvoke gdyż jest to jedyna oficjalna metoda na wstrzyknięcie naszego kodu do wątku UI. Czyli:
if(control.InvokeRequired) control.BeginInvoke(...)

Następna dyskusja:

Zapisywanie do jednego pliku




Wyślij zaproszenie do