Class using asynchronous multithreading returning null objects?

T

tcomer

Hello again, I've been struggling with this problem for two days now.
And either I'm getting a null object, or I'm overlooking something.

Basically what I have is this:

Form1 implements a class called ServerPropertyGrid object, which
implements a GameServer object. The GameServer object used a 'Player'
class which just holds player data. The 'GameServer' queries a game
server, and format the data for display/storage and also populates an
array of Player using the data, but keep in mind that is uses
asynchonous multithreading to handle the sockets.

What I'm trying to do is access the Player[] that is a part of the
GameServer object, from Form1 :)

GameServer.cs
----------------------
GetServerData(); // gets/stores all returned info from the server
PopulatePlayerData(); // initializes and populates m_playerList with
Player data
public Player[] Players{ get { return m_playerList; }} /////// this
returns just fine

ServerPropertyGrid.cs
--------------------------------
ShowServerData(); // displays all server data in the grid
public Player[] Players{ get { return this.players; }} /////////
players[0].Name prints out what it's supposed to, so it's not null
here
private void GetPlayers(){ this.players = gameserver.Players; }

Form1.cs
--------------
serverGrid.GetResponse(ip, port);
this.playerList = serverGrid.Players; /// PROBLEM LINE

in Form1 the serverGrid.Players object is null, and the code I've
provided is the only places that the objects are modified. Using
this.ServerPropertyGrid.GameServer.Players to access the Player array
throws a NullReferenceException, which doesn't make sense, because
it's not null unless I try to access it from Form1. I've tried
this.ServerPropertyGrid.GameServer.Players, and I've also tried
Invoking a "GetPlayers" method using a delegate which gets the
Players[] and assigns it to a local object - neither solutions worked.
Any ideas?

I have no problem with sharing the actual project, if it would help
make my problem more clear. Thanks
 
T

tcomer

Problem still exist, but I've changed the way that Form1 is accessing
the Player[] in GameServer. Just to make things a little more clear.
I'm accessing the Player[] from Form1 using something similar to
Player[] p = this.ServerPropertyGrid.GameServer.GetPlayers(); Stepping
through the program, I get this:

GameServer.GetPlayers(); FINE
ServerPropertyGrid.GameServer.GetPlayers(); FINE
Form1.ServerPropertyGrid.GameServer.GetPlayers(); RETURNS NULL

Hope my attempt at clarification helps.
 
P

Peter Duniho

Hello again, I've been struggling with this problem for two days now.
And either I'm getting a null object, or I'm overlooking something.

Basically what I have is this:

Form1 implements a class called ServerPropertyGrid object, which
implements a GameServer object.

When you write "implements", what you do mean? Because you obviously
don't mean what people normally mean.

Your class Form1 implements the class Form1. Sometimes classes also
implement an interface, but your post says that ServerPropertyGrid is a
class, and since C# doesn't have multiple inheritance and your Form1 class
almost certainly inherits Form, then even if ServerPropertyGrid was an
abstract class for some other class to actually implement, your Form1
could not be the class that implements it.

The same confusion concerns the idea of ServerPropertyGrid "implementing"
the GameServer class. Granted, you're more vague about the statement so
we could read all sorts of things into it, but given your previous use of
the word "implements" it seems likely that whatever guesses we make aren't
necessarily going to be correct.

So, what _is_ the actual relationship between those three classes? Please
try to describe it using the actual terminology that is commonly used in
C# programming. If you're unfamiliar with that terminology, rather than
just writing some word that you think sounds correct, be very explicit and
use complete phrases instead.
The GameServer object used a 'Player'
class which just holds player data. The 'GameServer' queries a game
server, and format the data for display/storage and also populates an
array of Player using the data, but keep in mind that is uses
asynchonous multithreading to handle the sockets.

So far, nothing you've posted actually describes any part of your code
that uses your asynchronous multithreading with sockets. Either it's not
relevant and should not have been mentioned in the first place, or it is
relevant and you've left out a very critical part of your problem
description.
[...]
in Form1 the serverGrid.Players object is null, and the code I've
provided is the only places that the objects are modified. Using
this.ServerPropertyGrid.GameServer.Players to access the Player array
throws a NullReferenceException, which doesn't make sense, because
it's not null unless I try to access it from Form1.

Well, in the expression "this.ServerPropertyGrid.GameServer.Players",
there are several things that _could_ be null. In fact, that expression
alone would not throw a NullReferenceException just because Players is
null, because that expression doesn't _do_ anything with the Players
property. Only until you tried to use the value retrieved from the
Players property would an exception occur.

So, either it's something else that's null, or you did not actually
provide an accurate description of what's throwing a
NullReferenceException.
I've tried
this.ServerPropertyGrid.GameServer.Players, and I've also tried
Invoking a "GetPlayers" method using a delegate which gets the
Players[] and assigns it to a local object - neither solutions worked.
Any ideas?

Well, the first thing that comes to mind, since it's what is often the
problem when people post questions like this, is that the Form1 class code
is not using the same ServerPropertyGrid reference that has the GameServer
instance and/or Players[] array. That is, you somehow have gotten two
instances of the ServerPropertyGrid class, and in one instance everything
looks fine, but in the other (which you use from Form1) the important
field hasn't been initialized.

An alternative explanation could be that you're either not calling
GetPlayers() soon enough and so the ServerPropertyGrid instance doesn't
have a valid players array yet. Or it gets called too early and winds up
overwriting an existing players array with a null. Of course, those two
explanations assume that the null reference really is the player array.
It's not at all clear from your description that that's the case.

Finally, since you mentioned that you're using threads, there is the
possibility that some variable that's being used in the code that's
relevant here should be marked as volatile and is not. This would allow
one thread to update the variable but another thread not see the change.
Frankly, this sort of bug is often hard to reproduce and you didn't
mention anything about the behavior being intermittent, so based on that
it doesn't seem like that's what you're running into. But it could be.
It's very hard to say without a real example of code.
I have no problem with sharing the actual project, if it would help
make my problem more clear. Thanks

Absolutely do _not_ share the entire project. Very few people, if any,
would be willing to read through a complete project.

But yes, you should definitely post a _concise_-but-complete example of
code that reliably demonstrates the problem. Concise meaning that you
have removed every last bit of code that is not _directly_ related to and
required for reproducing the problem. Complete meaning that the code can
be compiled as a complete executable, without any errors, and it will
execute and reproduce the problem.

As things stand now, the only advice that can be offered is conjecture.
And sometimes conjecture is correct, but usually it's not.

Pete
 
T

tcomer

Sorry, forgot about the Java programmers out there :) I just meant
"uses".

Form1 (System.Windows.Forms.Form)
ServerPropertyGrid (inherits from System.Windows.Forms.PropertyGrid)
GameServer (user defined - uses Player)
Player (user defined)
 
P

Peter Duniho

Sorry, forgot about the Java programmers out there :) I just meant
"uses".

I have no idea what the Java comment means. In any case, there's no place
in the world that "implements" is a synonym for "uses".
 
P

Peter Duniho

Problem still exist, but I've changed the way that Form1 is accessing
the Player[] in GameServer. Just to make things a little more clear.
I'm accessing the Player[] from Form1 using something similar to
Player[] p = this.ServerPropertyGrid.GameServer.GetPlayers(); Stepping
through the program, I get this:

GameServer.GetPlayers(); FINE
ServerPropertyGrid.GameServer.GetPlayers(); FINE
Form1.ServerPropertyGrid.GameServer.GetPlayers(); RETURNS NULL

Hope my attempt at clarification helps.

Is GameServer.GetPlayers() a static method? Is
ServerPropertyGrid.GameServer a static property? Either way, the syntax
above doesn't make any sense. You can't ask a nonsense question and
expect a sensible answer in return.

Also, how can the GetPlayers() ever return anything, null or otherwise,
given that according to your first post it has "void" as the return type?

I know you probably think I'm just harassing you or something. But the
fact is, your question just doesn't make much sense as it is. If you
really want help, you need to take to heart the comments I've made, and
re-present your question in a more logical, consistent, and _complete_
way. I noticed you replied to my first reply, but failed to answer _any_
of the questions I asked, and did not bother to provide any of the details
that I pointed out are necessary for anyone to really be able to answer
your question.

As far as I know, not a single person reading this newsgroup is psychic.
And without that skill, we can't answer the question as you've written it.

Pete
 
T

tcomer

I gotcha, I will try to be more clear and concise in my future
postings. At this point I'm uncapable of thinking clearly, but I've
solved the problem. So, thanks.
 
P

Peter Duniho

I gotcha, I will try to be more clear and concise in my future
postings. At this point I'm uncapable of thinking clearly, but I've
solved the problem. So, thanks.

And for the record, the problem was? Even a basic outline of what was
wrong might help someone in the future, in spite of the lack of a clear
problem description.

Most of the errors a programmer makes are not original. It stands to
reason whatever mistake existed before will exist again somewhere else. :)

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top