Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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

Aktivity
Avatar
Adam Ježek
Tvůrce
Avatar
Adam Ježek:15.3.2015 17:39

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
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
Odpovídá na Adam Ježek
sadlomaslox25:15.3.2015 18:14

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í
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
15.3.2015 18:14
Avatar
Adam Ježek
Tvůrce
Avatar
Odpovídá na sadlomaslox25
Adam Ježek:15.3.2015 18:18

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
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
Odpovídá na Adam Ježek
sadlomaslox25:15.3.2015 18:39

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.