[C#] button.Show() vanuit anderen Thread

Pagina: 1
Acties:
  • 417 views sinds 30-01-2008
  • Reageer

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Topicstarter
Mijn probleem is alvolgt. Ik heb een button op een form en als het form geladen word word er een nieuwe Thread gestart die wat dingen in een database update.

Op het form is een ProgressBar te zien die aangeeft hoever het process al is.

Als de database update klaar is word in dezelfde method word de Show method van de button aangeroepen.

Maar de button word nooit zichtbaar. Komt dit omdat de Show method in een anderen Thread word aangeroepen dan de MainThread. Als ik de Text propertie change gaat het wel goed. Dan komt er een anderen caption op de button.

Ik heb het nog snel even getest met een simpelen code: (de Visable propertie staat op false in design time)

C#:
1
2
3
4
5
6
7
8
9
10
private void Form1_Load(object sender, System.EventArgs e)
{
    Thread t = new Thread(new ThreadStart(showButton));
    t.Start();
}

private void showButton()
{
    cmdTest.Show();
}


Dit werkt weer wel: (de Visable propertie staat op true in design time.)
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
private void Form1_Load(object sender, System.EventArgs e)
{
    cmdTest.Hide();

    Thread t = new Thread(new ThreadStart(showButton));
    t.Start();
}

private void showButton()
{
    Thread.Sleep(1000);
    cmdTest.Show();
}


En dit werkt dus ook niet. Hoe komt dit en wat is een oplossing?

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Je zou kunnen detecteren of de gestarte thread klaar is met zijn werk, en indien zo de originele thread de Show laten uitvoeren

edit:
ow... misschien kun je bij de button beter het "enabled" property gebruiken zowiezo, dat werkt misschien wel beter

[ Voor 33% gewijzigd door MLM op 08-01-2005 15:53 ]

-niks-


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Topicstarter
MLM schreef op zaterdag 08 januari 2005 @ 15:51:
Je zou kunnen detecteren of de gestarte thread klaar is met zijn werk, en indien zo de originele thread de Show laten uitvoeren

edit:
ow... misschien kun je bij de button beter het "enabled" property gebruiken zowiezo, dat werkt misschien wel beter
Klopt, ik zou het kunnen proberen met events. Maar ik vraag me af waarom dit niet werk.

Het gebruik maken van de Visable propertie maakt geen verschil.

  • Juicy
  • Registratie: December 2000
  • Laatst online: 05:19
Alle bewerkingen op GUI controls moeten via de thread lopen die verantwoordelijk is voor de creatie van het dialoog. In jouw geval de mainthread. Kijk eens naar "invoke" voor meer info.

-


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Topicstarter
Juicy schreef op zaterdag 08 januari 2005 @ 16:06:
Alle bewerkingen op GUI controls moeten via de thread lopen die verantwoordelijk is voor de creatie van het dialoog. In jouw geval de mainthread. Kijk eens naar "invoke" voor meer info.
Waarom werkt de twee code dan wel en kan ik de Text propertie ook aanpassen?

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Topicstarter
Hoe kan ik nu de Method Show invoken dmv de Invoke method?

Ik heb het nu zo gedaan:

C#:
1
2
3
4
5
6
7
8
9
if(cmdOk.InvokeRequired)
{
    MethodInvoker mi = new MethodInvoker(cmdOk.Show);
    cmdOk.Invoke(mi);
}
else
{
    cmdOk.Show();
}


Zijn er nog anderen manieren. Of is dit gewoon de goede weg.

[ Voor 68% gewijzigd door pjvandesande op 08-01-2005 16:28 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:16
Je mag nooit Windows controls gaan aanpassen vanuit een andere thread dan de thread waarin ze gecreeërd worden; als je een andere thread iets moet laten aanpassen op je windows controls, dan moet je het idd met een 'invoke' doen.

Meestal maak ik voor taken die op een andere thread moeten gebeuren een class, met dan een aantal events waar je event-handlers kunt voor schrijven om je windows forms te gaan updaten (bv. om een vooruitgang te tonen).
Dit ziet er dan bv zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class MyTask
{

       private event EventHandler      _statusUpdated;

       public EventHandler  StatusUpdated
       {
             get
             {
                     ...
             }
             set
             {
                       ...
             }
       }

       public void Run()
       {
               Thread t = new Thread(new ThreadStart(PerformTasks);
               t.Run();
       }

        private void PerformTasks()
        {
        }

         // Thread safe method to invoke the event-handler
        private void OnStatusUpdated()
        {
              if( _statusUpdated != null )
              {
                     ISynchronizeInvoke c = _statusUpdated.Target as ISynchronizeInvoke;

                     if( c != null )
                     {
                             c.Invoke (_statusUpdated, new object[] {this, EventArgs.Empty});
                     }
                     else
                     {
                             _statusUpdated(this, EventArgs.Empty);
                     } 
              }
        }
}

https://fgheysels.github.io/


  • dotcode
  • Registratie: Augustus 2003
  • Laatst online: 17-05 21:04

dotcode

///\00/\\

ik zou even een try catch om je show() methode heen zetten en de exception laten printen. Ik kan me voorstellen dat de fout is dat het iets is als can not access a comopoment created in a diffrent thread. Zo iets heb ik namelijk wel eens gezien in een progje van me. De exceptie komt dan niet boven omdat hij niet in je main thread draait. Het is maar een gokje...

agg, ik zag niet dat whaomi al een antwoord had gegeven met een mooi vb er in.

[ Voor 11% gewijzigd door dotcode op 09-01-2005 16:05 ]


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

dotcode schreef op zondag 09 januari 2005 @ 16:04:
ik zou even een try catch om je show() methode heen zetten en de exception laten printen. Ik kan me voorstellen dat de fout is dat het iets is als can not access a comopoment created in a diffrent thread. Zo iets heb ik namelijk wel eens gezien in een progje van me. De exceptie komt dan niet boven omdat hij niet in je main thread draait. Het is maar een gokje...
In .NET 1.0 en 1.1 wordt hier geen exception op gethrowed, af en toe werkt het ook gewoon. Pas vanaf .NET 2.0 wordt hier een exception op gethrowed, en deze zie je dan ook, want alle threads draaien in Debug mode (als je tenminste debugt), dus alle exceptions in alle threads worden afgevangen.

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?

Pagina: 1