Komunikator - problemy z 2008
Witam,
pytanie odnośnie komunikatora z poradnika http://www.centrumxp.pl/dotNet/831,2,Komunikator_w_C.aspx
Napisałem program serwera zgodnie z poradnikem. Wszysko się kompiluje i działa dopóki nie kliknę na przycisk "Czekaj na polaczenie". Otrzymuję wtedy komunikat run-time errora: "Nieprawidłowa operacja między wątkami: do formantu 'txtLog' uzyskiwany jest dostęp z wątku innego niż wątek, w którym został utworzony."
i jeszcze typ wyjątku: [quote]+ o {Text = '((System.Windows.Forms.RichTextBox)(o)).Text' threw an exception of type 'System.InvalidOperationException'} System.Windows.Forms.RichTextBox[/quote]
Ma ktoś jakiś pomysł jak to naprawić?
Pozdrawiam,
Michał
Odpowiedzi: 6
dziala, dzieki ;)
Nalezy skorzystac z metody Invoke() formularza. Tzn. tworzysz delegata do metody, ktora rzuca tym bledem i nastepnie odpalasz na formie Invoke() podajac tego delegata jako parametr. Powinno dzialac :)
Problem występuje JEDYNIE w trybie debuggowania (po wciśnięciu f5 w Visualu), jeśli odpali się pliki exe bezpośrednio z folderu projektu - wszystko (poza rozłączaniem i działaniem zdarzenia FormClosed) działa poprawnie. Orientuj się może ktoś w czym może być problem? Tożto wręcz absurdalne.
Ściągnąłem źródło programu z końca poradnika. Programik ładnie działa (tzn pliki exe). Przekonwertowałem sobie projekt z Visuala 2005 na 2008 i... wyskakuje ten sam błąd co mi.
W komentarzach do tekstu poradnika ktoś miał ten sam problem co ja, nikt mu jednak nie odpowiedział.
Co do samego błędu - postaram się go przybliżyć. Mamy sobię kontrolkę Background Worker (a wlasciwie 2 takie kontrolki, wiec lacznie mamy 3 watki dzialajace na jednym RichTextBoxie). Zgodnie z poradnikiem robimy obsługę jednego z eventów:
private void Polaczenie_DoWork(object sender, DoWorkEventArgs e)
{
wyswietl(txtLog, "Czekam na polaczenie\n");
//(...)
}
a oto definicja metody wyswietl:
public void wyswietl(RichTextBox o, string text)
{
o.Focus();
o.AppendText(text);
o.ScrollToCaret();
txtWysylane.Focus();
}
a wszystko uruchamiane jest przez button:
private void cmdSluchaj_Click(object sender, EventArgs e)
{
if (cmdSluchaj.Text == "Czekaj na polaczenie")
{
Polaczenie.RunWorkerAsync();
cmdSluchaj.Text = "Rozlacz";
}
//(...)
}
Klikamy zatem button, po chwili uruchamia się Background Worker. Wywoluje on metode wyswietl i.... w tym momencie wszystko pada. Dochodzi do o.Focus(); i stwierdza, ze nie moze nic zrobic, bo inny watek stworzyl richtextboxa.
Tekst jak widac jest krotki, RichTextBox.Text probowalem nawet inicjalizowac i nie pomoglo nic. Nie zawiera tez zadnych niedozwolonych znakow.
Idzie to jakos naprawic?
Nie czytałem artykułu, ale mogę powiedzieć co jest dokładnym podmiotem problemu:
Atóż funkcja/metoda z jednego wątku (thread) nie mże wywołać innej metody/funkcji, która znajduje sięna drugim. To się często zdarza (mam na myśli to utrudnienie) przy pracy z Timer'ami, ale o tym może później...
Wracając do problemu: spróbuje go przeanalizować:
Operacja na właściwości Text w kontrolce RichTextBox spowodowała wyjątek o treści "InvalidOperationException", co oznacza że program próbował wykonać coś z tekstem zawartym w kontrolce, ale mu się nie powiodło. Inczej mówiać, ale właściwość Text była pusta (nic nie wpisałeś), albo zawierała niedozwolone znaki (program nie wziął tego pod uwagę), lub po prostu tekst był za długi...
Sprawdź czy przepisując z artykułu kod, niegdzie się nie pomyliłeś. Zwróć uwagę na linijki w których jest użyty owy RichTextBox.
Nie mogę Ci więcej pomóc z prostego powodu: jeszcze (jak isię nie myle) nikt nie zgłosić problemu z tym artykułem, więc można przepuszczać że jest on w porządku.
Strona 1 / 1