BackGroundWorker - pomożecie?

0

Nie umiem sobie poradzić z osługą kontrolki BackGroundWorker.
Możecie mi to jakoś wytłumaczyć?
Albo napisać kod, w którym zostaje utworzony wątek.

Thread t = new Thread(new ThreadStart(F));
t.Start();

Wątek ten ma wprowadzić tekst do kontroli label:

public void F()
{
label1.Text = "test";
}

Niestety powyższy kod nie działa.
Pomóżcie..

0

Tak latwo nie jest - nie mozesz z osobnego watku zmieniac innego watku - w szczegolnosci komponentow formatki. Gdzies bylo ostatnio ale podam z pamieci, wiec sprawdz pozniej czy nie ma bledow:

Label label = new Label();
...

delegate void SendMessage(String message, Object object);

private void SetText(String message, Object object)
{
  ((Label)object).Text = message;
}

private void SetLabel(String message, Label label)
{
  this.Invoke(new SendMessage(SetText), new object [] {message, label});
} 

private void Run()//praca watku
{
  SetLabel("watek dziala", label);
}

private void StartThread()
{
  new Thread(new ThreadStart(Run)).Start();
}

pozdrawiam
johny

0

Dzięki, kod działa po wprowadzeniu pewnych modyfikacji...

        delegate void SendMessage(String message, Object Object);

        private void SetText(String message, Object Object)
        {
  
        ((Label)Object).Text = message;

        }

        private void SetLabel(String message, Label label1)
        {
        this.Invoke(new SendMessage(SetText), new object [] {message, label1});
        } 

        private void Run()//praca watku
        {
        SetLabel("watek dziala", label1);
        }

        private void StartThread()
        {
        new Thread(new ThreadStart(Run)).Start();
        }

//edit
To jeszcze raz ja:
nie wiem czemu, po przełożeniu tego kodu do zdefiniowanej przeze mnie klasy pojawił się błąd:
Error 1 'Test.Form1.Download' does not contain a definition for 'Invoke'
O co tu może chodzić?

0

Invoke jest metoda formularza, wiec odpowiednio ja wywolaj. Metoda ta krotko mowiac wywoluje delegacje z watku formularza, gdzie zmiana czegokolwiek jest juz dozwolona - dlatego tak naokolo trzeba podawac.

PS. A jakich modyfikacji, bo nie zauwazylem roznicy? Tak z ciekawosci pytam :)

pozdrawiam
johny

0

Zamiast:
delegate void SendMessage(String message, Object object);
ma być np:
delegate void SendMessage(String message, Object <font color="red">obiekt</font>);

0

Niestety pojawił się kolejny problem. Proszę o pomoc:
Problem dotyczy tym razem kontrolki BackgroundWorker i przestrzeni nazw.
Załóżmy, że:
-metodą Drag and Drop przeciągnąłem BackgroundWorker na formę.
-nadałem takie nazwy funkcji:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
   // tutaj coś, w tej chwili nie jest to istotne
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
   // tutaj coś, w tej chwili nie jest to istotne
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
   // tutaj coś, w tej chwili nie jest to istotne
}

-zbudowałem klasę K.
-w konstruktorze klasy K umieściłem między innymi:

public K(ref BackgroundWorker backgroundWorker1)
{
this.backgroundWorker1 = backgroundWorker1;
}

I teraz chciałbym aby owe 3 funkcje kontrolki BackgroundWorker znajdowały się właśnie w klasie K
jak to zrobić?

0

Umiesc te metody w tej klasie, nastepnie w klasie, w ktorej jest BackgroundWorker przypisz ich delegacje do zdarzen. Prawdopodobnie ze statycznymi metodami nie zadziala, ale zgaduje.

pozdrawiam
johny

0

Można wiedzieć (przynajniej mniej więcej) jak przypisać ich delegacje do zdarzeń?
(początkujący...)
Aha, no i dzięki bardzo za zainsteresowanie tematem.

PS: (O ten fragment kodu chodzi?)
W pliku Form1.Designer.cs w metodzie InitializeComponent() :

this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
this.backgroundWorker1.DoWork +=
               new System.ComponentModel.DoWorkEventHandler(
               this.backgroundWorker1_DoWork);
this.backgroundWorker1.RunWorkerCompleted +=
               new System.ComponentModel.RunWorkerCompletedEventHandler(
               this.backgroundWorker1_RunWorkerCompleted);
this.backgroundWorker1.ProgressChanged +=
               new System.ComponentModel.ProgressChangedEventHandler(
               this.backgroundWorker1_ProgressChanged);
0

Tak, to ten fragment - w zasadzie musisz tylko wskazac metody z tamtej klasy, zeby dzialalo. Czyli tak samo jak cala reszta tylko jeszcze wskazanie w jakiej klasie metoda jest. I powinno dzialac.

pozdrawiam
johny

0

Poddaje się... :-(
Jak to mam zrobić...?
Nie mogę po prostu zamienić lini
this.backgroundWorker1_ProgressChanged
na np:
K.backgroundWorker1_ProgressChanged
bo musiałbym przemienić te 3 klasy na static, następnie sam obiekt backgroundWorker1 musiałbym zamienić na static, a następnie obiekt label1, progressBar1, itd, itd...

0
Roland napisał(a)

Poddaje się... :-(
Jak to mam zrobić...?
Nie mogę po prostu zamienić lini
this.backgroundWorker1_ProgressChanged
na np:
K.backgroundWorker1_ProgressChanged
bo musiałbym przemienić te 3 klasy na static, następnie sam obiekt backgroundWorker1 musiałbym zamienić na static, a następnie obiekt label1, progressBar1, itd, itd...

Witam po dluzszym czasie.

O ile zrozumialem to chodzi Ci o to, zeby miec obsluge BackgroundWorker w klasie K. Ja to zrobilem tak:

klasa K:

using System;

namespace BackgroundWorker
{
	public class K
	{
		System.ComponentModel.BackgroundWorker bWorker;
		public K(System.ComponentModel.BackgroundWorker BackgroundWorker1)
		{
			this.bWorker = BackgroundWorker1;
			this.bWorker .DoWork += new System.ComponentModel.DoWorkEventHandler(this.BackgroundWorker1DoWork);
			this.bWorker .RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.BackgroundWorker1RunWorkerCompleted);
			this.bWorker .ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.BackgroundWorker1ProgressChanged);
			
		}
		void BackgroundWorker1DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
		{
			//cos
		}
		
		void BackgroundWorker1ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
		{
			//cos
		}
		
		void BackgroundWorker1RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
		{
			//cos
		}

	}
}

Klasa okienka:

		private void InitializeComponent()
		{
			this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
			this.SuspendLayout();
			// 
			// backgroundWorker1
			// 
			//usunieta sekcja przypisania zdarzen do BackgroundWorker
			// 
			// MainForm
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(292, 266);
			this.Name = "MainForm";
			this.Text = "BackgroundWorker";
			this.ResumeLayout(false);
		}
		private System.ComponentModel.BackgroundWorker backgroundWorker1;

Ta powyzej wygenerowana z usunieta sekcja jak w komentarzu.

Mam nadzieje, ze to miales na mysli.

pozdrawiam
johny

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