[C#] Event is altijd null

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

Topicstarter
Ik ben bezig met een method die lang nodig heeft voor z'n taak, daarom gebruik ik een BackgroundWorker om deze op de achtergrond uit te voeren, maar natuurlijk wil ik wel het de voortgang bijhouden en weten wanneer hij klaar is is ook wel prettig. :+ Daarom heb ik 2 custom events, 1 om de voortgang bij te houden en 1 om aan te geven dat hij klaar is. Niet al te ingewikkeld dus. :)

Het probleem is alleen dat mijn ProgressChangedEvent altijd null is zodra ik deze probeer af te vuren. Een korte testcase:
C#:
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
class TableRenderer : Renderer
    {
        private static BackgroundWorker worker;

        new public delegate void ProgressChangedEvent(object sender, RenderProgressChangedEventArgs ca);
        new public delegate void RenderCompleteEvent(object sender, RenderCompleteChangedEventArgs ca);

        new public event RenderCompleteEvent RenderComplete;
        new public event ProgressChangedEvent ProgressChanged;

        public TableRenderer()
        {
        }

        public override void Render()
        {
            worker = new BackgroundWorker();
            worker.DoWork += ToHtml;
            worker.RunWorkerAsync();
        }


        private void ToHtml(object sender, DoWorkEventArgs e)
        {
            ProgressChanged(this, new RenderProgressChangedEventArgs(0, 1));
            RenderComplete(this, new RenderCompleteChangedEventArgs(output.ToString()));
        }
    }

Zodra hij bij ProgressChanged aankomt krijg ik een NullReferenceException, en als ik hover over die regel blijkt ProgressChanged inderdaad null te zijn. RenderComplete is wel gewoon een RenderCompleteEvent, en die wordt ook gewoon afgevuurd.

Wat zoekwerk laat zien dat er nog een manier is om events aan te geven, en die heb ik dus ook geprobeerd:
C#:
1
2
public event EventHandler<RenderProgressChangedEventArgs> RenderProgressChanged;
public event EventHandler<RenderCompleteChangedEventArgs> RenderComplete;

Helaas heeft dit hetzelfde probleem, dus dat is ook geen oplossing.

Zoeken naar "Object reference not set to an instance of an object." heeft niet zoveel nut, ook niet in combinatie met "C# events". Het is immers zo ongeveer de meest voorkomende foutmelding in C#, met de bijbehorende hoeveelheid pagina's die erover gaan. :X :( Daarom hoop ik dat iemand hier me verder kan helpen.

Als ontwikkelomgeving gebruik ik VS2005 Professional SP1 met de Vista fix, op Windows Vista Business SP1 (EN). Dit is dus met het .NET framework 2.0, versie 2.0.50727 SP1 om precies te zijn. Ik heb ook getest op een machine met Windows XP Pro SP3 (EN), met VS2005 Professional SP1 zonder Vista fix, met dezelfde versie van het .NET 2.0 framework. Daarop krijg ik precies hetzelfde probleem.

Sole survivor of the Chicxulub asteroid impact.


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Waarom maak je die BackGroundWorker static ?
Waarom definieer je die delegates als 'new' ? En die events ook ? Heeft 'Renderer' (waar je van overerft) nl. ook al die events en wil je ze hiden ?

Dat je events null zijn, kan heel goed zijn, want ik zie nergens dat je een event-handler aan die event hebt gekoppeld...
Als je je event wilt raisen, moet je zowiezo checken of je event null is of niet (of er een eventhandler aan hangt).
Maar, de BackgroundWorker heeft toch ook een ProgressChanged / WorkComplete (oid) event ?

Kan je jouw class trouwens niet zo maken:
C#:
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
public class TableRenderer : Renderer
{
     private BackGroundWorker worker = new BackGroundWorker();

     public event ProgressChangedEventHandler ProgressChanged
     {
          add
          {
               worker.ProgressChanged += value;
          }
          remove
          {
               worker.ProgressChanged -= value;
          }
     }

     public event RunWorkerCompletedEventHandler Completed
     {
          add
          {
               worker.RunWorkerCompleted += value;
          }
          remove
          {
               worker.RunWorkerCompleted -= value;
          }
     }

     public override void Render()
     {
         worker.DoWork += ....
         worker.RunWorkerAsync();
     }
}


Dan moet je nog in je 'client' (als in: diegene die gebruik maakt van je renderer) dit doen:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TableRenderer r = new TableRenderer();
r.ProgressChanged += new ProgressChangedEventHandler (OnProgressChanged);
r.Completed += new RunWorkerCompletedEventHandler(OnComplete);
r.Render();

...

private void OnProgressChanged( ... )
{
    Console.WriteLine ("progresschanged");
}

private void OnComplete( ... )
{
    Console.WriteLine ("finished");
}

[ Voor 57% gewijzigd door whoami op 05-06-2008 21:13 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

Topicstarter
whoami schreef op donderdag 05 juni 2008 @ 21:05:
Waarom maak je die BackGroundWorker static ?
Foutje, maar dat maakt verder voor het probleem niet uit.
Waarom definieer je die delegates als 'new' ? En die events ook ? Heeft 'Renderer' (waar je van overerft) nl. ook al die events en wil je ze hiden ?
Ja, normaal gesproken wil ik die niet hiden maar nu deed ik dat om te proberen of dat dat wel werkte. Dat doet het dus niet. :P
Dat je events null zijn, kan heel goed zijn, want ik zie nergens dat je een event-handler aan die event hebt gekoppeld...
Buiten mijn class voeg ik eventHandlers toe, ik wil de events niet binnen mijn class opvangen.
Als je je event wilt raisen, moet je zowiezo checken of je event null is of niet (of er een eventhandler aan hangt).
Dat doe ik in de OnRenderComplete() en de OnRenderProgressChanged() methods in Renderer, die heb ik gemaakt zoals op deze pagina staat.

Sole survivor of the Chicxulub asteroid impact.


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Heb mijn post even wat uitgebreid :Y)

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 03:43
Als je event null is, is er geen eventhandler aan gekoppeld (zoals whoami al zegt). Doe je niet per ongeluk een Render() voordat je de eventhandlers aan de renderer hebt gekoppeld? En, wederom zoals whoami al zegt, de backgroundworker heeft al Progress en Completed events, waarom het wiel opnieuw uitvinden?

Roomba E5 te koop