Diskuze: C# - Vlákno nemůže získat přístup k objektu a statické třídy

C# .NET .NET (C# a Visual Basic) C# - Vlákno nemůže získat přístup k objektu a statické třídy American English version English version

Avatar
Adam Ježek
Tým ITnetwork
Avatar
Adam Ježek:

Zdravim,
mam v C# serial port listener

private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
           SerialPort sp = (SerialPort)sender;
           string indata = sp.ReadExisting();
           recdata(indata);
       }

Problém je v tom, že když chci zavolat funkci recdata, vyhodí to u ní chybu. Na SO mi řekli, ať ji udělam statickou. Tak sem připsal static i do definice recdata(), sice jí to zavolá, ale ta zase vyhazuje chyby při přístupu k proměnným, další rada ze SO byla udělat všechno statické (to fakt ne).

Zkusil sem u serialport listeneru z private static void udělat jenom private void (všechna static šly zase pryč), to funguje skoro všechno, můžu měnit proměnné, volat funkci recdata (nestatickou) atd, ale když se pokusim jakkoliv (přímo i nepřímo vyvoláno listenerem) změnit data v labelu nebo něčem na formuláři (WPF), např

opertxt.Text = "Nepřihlášen";

, tak vyhodí chybu:

An unhandled exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll

Additional information: Volající vlákno nemůže získat přístup k tomuto objektu, protože jej vlastní jiné vlákno.

Co s tim?
Díky

Editováno 15.3.2015 17:42
Odpovědět 15.3.2015 17:39
Pokud chceš odpovědět, klikni na odpovědět. Pokud chceš vložit zdroják, klikni na vložit zdroják (</>)
Avatar
Odpovídá na Adam Ježek
sadlomaslox25:

jednoducha odpoved:
misto

opertxt.Text = "Nepřihlášen";

napis

Dispatcher.Invoke((Action) (() => opertxt.Text = "Nepřihlášen"));

slozita:
serial port listener bezi na vlastnim vlakne, takze data co posila posila z jineho vlakna nez je UI vlakno. to je problem, protoze UI controly jako buttony a labely muze menit jen UI vlakno. abys mohl tyto prvky zmenit i z jineho vlakna je treba udelat funkci, kde chces menit tyto prvky a tuto funkci zavolat pomoci objektu Dispatcher, ktery zavola danou funkci s kontextem UI, coz nezpusobi tuto chybu.

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět 15.3.2015 18:14
Avatar
Adam Ježek
Tým ITnetwork
Avatar
Odpovídá na sadlomaslox25
Adam Ježek:

Díky moc, funguje. Jenom nevadí tomu že to může zavolat kromě listener vlákna i UI vlákno? Chybu to sice nevyhodilo, ale aby to tam nedělalo neplechu (použita jednodušší verze)

Editováno 15.3.2015 18:19
Nahoru Odpovědět 15.3.2015 18:18
Pokud chceš odpovědět, klikni na odpovědět. Pokud chceš vložit zdroják, klikni na vložit zdroják (</>)
Avatar
Odpovídá na Adam Ježek
sadlomaslox25:

nevadi to nicemu jen to "teoreticky" snizuje vykon. pro nesnizovani vykonu se pouziva jeste

if (!Dispatcher.CheckAccess())
    //volani pres invoke
else
    //primy pristup
 
Nahoru Odpovědět 15.3.2015 18:39
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 4 zpráv z 4.