Problem z blokowaniem formy przez wątek.

0

Próbuję stworzyć wątek, który nie zablokuje mi interfejsu (windowsforms) jednocześnie uaktualniając w nim kontrolki. Obecnie dzieje się tak, że na interfejsie nie da się teoretycznie niczego nacisnąć, ale jak nacisnę i poczekam to po jakimś czasie (kilku operacjach czytania) kliknięcie w interfejs zadziała, tak samo z przesunięciem formy.
Przybliżona zasada działania:
Przycisk Start => otworzenie void start => stworzenie nowego watku dla thr (watek2) thr.isbackground = true i thr.start() => kody co się dzieje dalej poniżej. walczę z tym kilka dni już, próbowałem dawać INVOKE wszędzie gdzie tylko można na różne sposoby, pewnie już za dużo tego namieszałem.

void watek2()
		{
			BeginInvoke (new Action(
				() =>
				{
			czytanie();
			chart.Invoke(new Action(delegate ()
			{
				chart.Series["OD"].Points.AddXY(DateTime.Now.ToLongTimeString(),c_data);
				if (chart.Series["OD"].Points.Count>119)
				{
					chart.Series["OD"].Points.RemoveAt(0);
					chart.ResetAutoValues();
				}				
			                        }));
			                      
			if (b_start.Enabled == false)
			{
			watek2();
			}	
				}
			));
			
		} 		
		void czytanie()
		{
						BeginInvoke (new Action(
				() =>
				{
			Action akcja = () => z_data = sp_1.ReadLine();
			this.BeginInvoke(akcja);	
			Action akcja2 = () => rtb_1.Text = z_data;
			this.BeginInvoke(akcja2);
			    
			if (z_data.StartsWith("g210"))
			    {
					z_data2 = z_data.Split(new char[] {' '});
					if (z_data2[1].StartsWith("E"))
					{}
					else
					{
					c_data=Convert.ToDouble(z_data2[1], System.Globalization.CultureInfo.InvariantCulture);
					}
			    }
				}
			   )); 
		}

Ktoś ma pomysł co robię źle? Mam problem z obsługą wątków jeżeli mają aktualizować kontrolki a nie tylko pobierać z nich dane.

1

Może Ci się przyda :) , ja odwołuje się do kontrolek dodając do forms lub usercontrol właściwość

public string Opis
		{
			get { return lbl_opis_postepu.Text; }
			set
			{
				try
				{

					if (this.InvokeRequired)
					{
						this.Invoke(
							new MethodInvoker(
								delegate { lbl_opis_postepu.Text = value; }
								)
							);
					}
					else
						lbl_opis_postepu.Text = value;
				}
				catch (Exception)
				{

				}

			}
		}

dzięki czemu kod sam sprawdza czy jest uruchamiany z wątku pobocznego czy wątku głównego

0

Obydwa kody są okropne. @PicassoPn nie wiesz, do czego służą właściwości. Właściwości używa się do ustawiania lub odczytywania jakiejś prostej wartości. Tam nie powinno być logiki ani obliczeń. Jest od tego kilka wyjątków, ale to nie jest jeden z nich.

Już wiele razy pisałem, jak to zrobić dobrze. Np tu: Dodawanie item'ów do Listy z kilku wątków na raz w jednym momencie

Zrób to tak, jak w tym kodzie.

0

Juhas dzięki za odpowiedź. Poradziłem sobie czymś takim:

label1.Invoke((MethodInvoker)delegate { label1.Text = data.ToString(); });

po sprawdzeniu if(InvokeRequired)

Teraz następny mój problem. Mam obiekt w FORM1, chcę wywołać za pomocą przycisku FORM2, w którym będę zmieniał atrybuty obiektu z FORM1. Jak dostać się w FORM2 do np. labelu w FORM1 aby zmienić w nim text?

0

Tak jak do dowolnego obiektu1 w obiekcie2, przekazać jego referencję, na przykład w konstruktorze, a potem wywołać odpowiednią metodę.
Ewentualnie zainteresować się wzorcem np. MVP, ale to może nie mieć sensu na Twoim etapie.

0

Dzięki za odpowiedzi. Mam pierwszą wersję programu. Wszystko śmiga u mnie na komputerze(Win10), ale na Win7 docelowym nie chce działać, wyskakuje System.IO.IOException. Stworzyłem u siebie wirtualke z Win7, postawiłem system, zainstalowałem aktualizacje i .net framework najnowszy i jest to samo. Macie pomysł? Problem występuje przy otrzymaniu danych z portu COM. Wcześniej całe okno się pojawia, zmiana języka, przyciski, ustawienie portu COM (też czytanie aktywnych portów) działa. Program się wysypuje po otrzymaniu pierwszej danej z portu.
Teraz instaluje na wirtualce VS żeby skopiować tam projekt i zobaczyć czy na niej się skompiluje.
Edit
Program na wirtualce Win7 się kompiluje ale wywala go w tym samym momencie. Dodatkowo po wywaleniu VS podaje komunikat:
The application is in break mode
Your app entered a break state, but there is no code to show becouse all threads were executing external code (typically system or framework code).
:(
Edit2
Napisałem program na wirtualce jeden przycisk, jeden richtextbox i serial port. Po naciśnięciu przycisku ma sp1.readline() i dzieje się to samo.
Edit3
Znalazłem taki wątek w szukaniu odpowiedzi:
http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport
Chyba problem występuje dla wielu przypadków. :/
Edit4
Pomógł Nuget i GodSharp.SerialPort, Dzięki za pomoc, pozdrawiam!

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