Diskuze: Přístup k formuláři z jiné třídy a vlákna

C# .NET .NET (C# a Visual Basic) Přístup k formuláři z jiné třídy a vlákna American English version English version

Avatar
aurus
Člen
Avatar
aurus:

Ahoj,

nemám obsáhlé zkušenosti v multi-threadingu a potřebuji radu.
Mám formulář, při zobrazení formuláře spustím backgroundworker vlákno v němž je nekonečný cyklus hledání zařízení ve své vlastní třídě, kterou vytvořím při spuštění vlákna.
Potřebuji při nalezenízařízení tomto externím vláknu vložit na formulář několik komponent (label, pictureBox..), neboli potřebuji přistoupit do kolekce controls a přidat položky z externí třídy, kter je vytvořen na externím vlákně.

Prosím o radu, topím se v tom měsíc.
Děkuji moc

 
Odpovědět 2.2.2014 17:39
Avatar
mario1
Člen
Avatar
mario1:

pokud použiješ komponentu BackgroundWorker tak v obluze jeho události RunWorkerCompleted můžeš rovnou přidat kontrolky na formulář bez použití Invoke,
nebo použít Invoke pokud chceš ovládat form z jiného vlákna,
nebo využít Synchronizati­onContext a metodu Post a pak už nemusíš řešit Invoke

Tupej příklad jak by to šlo udělat, ale osobně bych to řešil přes vzor MVP-Passive View

formulář Form1:
public partial class Form1:Form
{
  private Searcher searcher;
  public Form1()
  {
    InitializeComponent();
    searcher = new Searcher();
    searcher.Searched += new EventHandler<Searcher.ResultEventArgs>(searcher_Searched);
  }

  void searcher_Searched(object sender, Searcher.ResultEventArgs e)
  {
    if(this.InvokeRequired)
      this.Invoke((MethodInvoker)(()=>{createControls(e)}));
    else
      createControls(e);
  }

  createControls(Searcher.ResultEventArgs e)
  {
    Label label = new Label();
    label.Text = e.LabelText;
    label.Location=new Point(10,20);
    //.....
    this.Controls.Add(label);
  }
}



a v konstruktoru formuláře zaregistrovat dokončené hledání
searcher.Searched
v obsluze události formuláře Shown spustit


class Searcher
{
  public class ResultEventArgs : EventArgs
  {
    public string LabelText;
    public string PicturePath;
  }

  public event EventHandler<ResultEventArgs> Searched = delegate{};

  private Thread serachingThread = null;

  private object _lock = new object();

  public void StartSearchingAsync()
  {
    lock(_lock)
    {
      if(serachingThread != null)
        return;
      serachingThread = new Thread(doSearch)
      serachingThread.Start();
    }
  }

  private void doSearch()
  {
    while(true)
    {
      if(podminkaSplnena)
      {
        ResultEventArgs res = getSomeData(); //naplnit potřebná data
        Searched(this, res);
      }
      Thread.Sleeep(10); //čekat aspoň 10ms pokud by došlo k rychlému cyklení
    }
  }
}
Editováno 7.2.2014 11:28
 
Nahoru Odpovědět 7.2.2014 11:26
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 2 zpráv z 2.