[C#] Object op MainForm updaten vanuit een thread

Pagina: 1
Acties:

  • Bint
  • Registratie: Juli 2002
  • Laatst online: 14:52
Dag,

Ik ben op dit moment bezig met het botwar project hier op tweakers, en heb dit aangepakt om c# te leren. Dit omdat ik op mijn stageopdracht in C# moet gaan programmeren, en er nog helemaal geen ervaring mee heb.


Ik wil de GUI en botcode gescheiden houden, omdat dat "hoort" ;)
Maar nu dus het volgende: Als er dus worldinfo binnenkomt, wordt die geupdateted. Dit wil ik dan ook in een textBox op mijn mainForm laten zien, zodat ik weet dat het verwerkt wordt. Maar ik krijg dit totaal niet voor elkaar.

Ik heb
[rml]whoami in "[ C#] button.Show() vanuit anderen Thread"[/rml]
[rml][ C#] Nieuw window openen, thread loopt vast?[/rml] en
http://www.gekko-software.nl/DotNet/Art05.htm

al doorgenomen, maar ik krijg het maar niet voor elkaar. Waarschijnlijk ben ik er te dom voor ;)
Kan iemand mij aub helpen, want ik denk dat ik er enorm veel van zou leren. (En ik kan weer verder met het projectje )

PS: wat linkjes naar (of een linkje) naar informatie over eventhandlers, delegates en invokes in C# zouden ook wel handig zijn)

Mainform:
code:
1
2
3
4
private void button1_Click(object sender, System.EventArgs e)
        {
            Bot B = new Bot ("bint");
        }


bot.cs:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Bot
{
  public  Bot(string Name)
  {
    _Protocol = new Protocol(Name);
    _Protocol.OnWorldInfo+=new Protocol.WorldInfoHandler(s_OnWorldInfo);
  }
  
  s_OnWorldInfo(WorldInfo wi)
  {
    _WorldInfo = wi;
  }
}


protocol.cs
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Protocol
{
  public delegate void WorldInfoHadler(WorldInfo WorldInfo);
  private Thread _BotThread;
  public event WorldInfoHalder OnWorldInfo;

  public Protocol(string Name)
  {
    _BotThread = new Thread(new ThreadStart(BotThread))
    _BotThread.Start();
  }
  
  private BotThread()
  {
     HandleWorldInfo(param);
  }

  private void HandleWorldInfo(string param)
  {
    OnWorldInfo(new WorldInfo(param));
  }
}


Het is natuurlijk niet de volledige code, en er zitten tikfouten in, omdat ik het maar even vlug heb neergezet, maar je zult het idee snappen.

Memories of yesterday, will grow, but never die


  • SlowMeDown
  • Registratie: Mei 2003
  • Laatst online: 15-04 08:14
Google op ISynchronizeInvoke en je zult genoeg informatie vinden...

  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 13-04 14:28
Denk dat dit topic je verder kan helpen: [rml][ C#] Hoe een form element benaderen vanuit een andere class[/rml]

Opmerking: Je moet er nog wel rekening mee houden dat wanneer je botcode in een aparte thread draait (wat wel waarschijnlijk is), je wel nog moet Invoken wil je van daaruit dingen aanpassen op je GUI.

[ Voor 42% gewijzigd door riezebosch op 06-01-2006 01:37 ]

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • Bint
  • Registratie: Juli 2002
  • Laatst online: 14:52
bedankt, dat was effe een hele duidelijke post voor mij.

Maar in mijn geval gebeurd er dus het volgende:

als ik op een button klik, dan wordt er een object aangemaakt. In die constructor worden weer wat dingen uitgevoerd, oa een private _Protocol = new Protocol(Name)..
Daarin wordt dan een thread gestart, en eigenlijk alle messages afgehandeld.

Moet ik dus die _Protocol public maken, zodat ik vanuit mijn mainForm events eraan kan hangen??

Memories of yesterday, will grow, but never die


  • whoami
  • Registratie: December 2000
  • Laatst online: 18:20
Je start dus een thread in je constructor ? Is dat wel een goed idee ? Ik bedoel, ... is het niet beter om expliciet te kunnen zeggen 'start die verwerking nu'.

https://fgheysels.github.io/


  • Bint
  • Registratie: Juli 2002
  • Laatst online: 14:52
Als die bot wordt gecreeerd, dan mag ie van mij meteen connecten met de server, en data binnenkrijgen.

Als dit fout is, niet netjes, of iets anders, hoor ik het graag, want ik leer er alleen maar meer van...

dit is er eigenlijk wat er allemaal gebeurd:
C#:
1
2
3
4
5
6
7
8
9
public Protocol(string BotName, string Password)
        {
            _Connection = new Connection ();
            SendVersion();
            SendUserName(BotName, Password);
            _Running = true;
            _BotThread = new Thread(new ThreadStart(BotThread));
            _BotThread.Start ();
        }


Is het dan slimmer om die BotThread ergens anders te laten starten? En ik moet em dus public maken, wil ik er events aan kunnen hangen in het MainForm?

Memories of yesterday, will grow, but never die


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

in de MSDN zoeken op InvokeRequired (property) zal je al wat meer geven over hoe je GUI elementen moet veranderen vanuit andere classes.

basically is het dit:
code:
1
2
3
4
5
6
7
public string MyProperty(string param)
{
  if (InvokeRequired)
      Invoke(...,param) // << opzoeken ;)
  else
     DoeIetsMetParam();
}


wat threads betreft:
http://www.yoda.arachsys.com/csharp/multithreading.html is een zeer goeie uitleg over Multi-Threading binnen .NET (uitgelegd met C#)

bovendien hou jij je niet aan de C# naamgeving... mss ook maar eens opzoeken in de MSDN.

wat delegates betreft staat in de MSDN ook een goeie uitleg afaik...

ASSUME makes an ASS out of U and ME


  • whoami
  • Registratie: December 2000
  • Laatst online: 18:20
Bintje schreef op vrijdag 06 januari 2006 @ 10:35:
Als die bot wordt gecreeerd, dan mag ie van mij meteen connecten met de server, en data binnenkrijgen.

Als dit fout is, niet netjes, of iets anders, hoor ik het graag, want ik leer er alleen maar meer van...

dit is er eigenlijk wat er allemaal gebeurd:
C#:
1
2
3
4
5
6
7
8
9
public Protocol(string BotName, string Password)
        {
            _Connection = new Connection ();
            SendVersion();
            SendUserName(BotName, Password);
            _Running = true;
            _BotThread = new Thread(new ThreadStart(BotThread));
            _BotThread.Start ();
        }


Is het dan slimmer om die BotThread ergens anders te laten starten? En ik moet em dus public maken, wil ik er events aan kunnen hangen in het MainForm?
Het is gewoon beter om die thread expliciet te starten. Op die manier heb je nog eerst de mogelijkheid om je events van je Protocol class te binden aan eventhandlers die op je form staan.

https://fgheysels.github.io/


Verwijderd

Maak gebruik van de AsyncOperation class:
When you implement a class according to the Asynchronous Pattern for Components, you may need to track the lifetime of each asynchronous operation invoked on an instance of your class. The AsyncOperation class provides ways to track and report the progress of an asynchronous task.
Zie MSDN en Google voor meer informatie hierover.

Onderstaande link kan ook interessant zijn:
http://www.codeproject.com/csharp/LaunchProcess.asp

  • simon
  • Registratie: Maart 2002
  • Laatst online: 17:03
Klinkt misschien noobie (ben pas begonnen met C#) maar je zou toch ook een reference kunnen maken naar 'this'. Ik weet niet of dit ranzig is, maar als je 'this' mee geeft als reference bij de constructor kun je 'alles' met die class.

|>


  • Bint
  • Registratie: Juli 2002
  • Laatst online: 14:52
Simon schreef op vrijdag 06 januari 2006 @ 11:03:
Klinkt misschien noobie (ben pas begonnen met C#) maar je zou toch ook een reference kunnen maken naar 'this'. Ik weet niet of dit ranzig is, maar als je 'this' mee geeft als reference bij de constructor kun je 'alles' met die class.
persoonlijk vind ik dat heel ranzig om te doen. Verder wordt er een andere thread gestart, en ik geloof dat je objecten uit een andere thread (in dit geval de STAThread) niet mag aanspreken. En ik wil ook nog eens de UI en de andere code gescheiden houden, dus dat is voor mij geen oplossing. Toch bedankt voor het meedenken. (Ik kan me trouwens herinneren dat we op school zo ooit een project hebben gemaakt)

Memories of yesterday, will grow, but never die


Verwijderd

Simon schreef op vrijdag 06 januari 2006 @ 11:03:
Klinkt misschien noobie (ben pas begonnen met C#) maar je zou toch ook een reference kunnen maken naar 'this'. Ik weet niet of dit ranzig is, maar als je 'this' mee geeft als reference bij de constructor kun je 'alles' met die class.
Gaat niet werken. Controls zijn over het algemeen niet thread safe. Je kunt de control dus wel meegeven aan je Business klassen(wat zoiezo ranzig is), maar aanroepen vanuit andere threads worden niet gesynchroniseerd met de thread waarin de UI draait. Verder geeft VS 2005 .NET een exceptie als je dit doet.

  • simon
  • Registratie: Maart 2002
  • Laatst online: 17:03
Weer wat geleerd :)

|>

Pagina: 1