Skip to main content
broken link fixed, cf. https://meta.stackoverflow.com/a/406565/4751173
Source Link
  • Tasks: Do I need to dispose of Tasks?

  • VisualCell instances: they have the same lifetime as your main form, and the application will end (with all resources reclaimed by the O/S) when your main form closes.

  • Tasks: Do I need to dispose of Tasks?

  • VisualCell instances: they have the same lifetime as your main form, and the application will end (with all resources reclaimed by the O/S) when your main form closes.

replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link
reply to comments
Source Link
ChrisW
  • 12.9k
  • 1
  • 34
  • 76

isn't the point of the managed garbage collector to dispose of objects that aren't used anymore for me?

Yes. The garbage collector might take a while to run, though. For example if you open a file and then let go of the open file without disposing it, the O/S file handle will remain open until the garbage collector reclaims the object; during that time, you can't reopen/reuse the file.

Similarly some resources are in limited supply: you might only be allowed a few SQL connections, or SQL transaction, or GDI objects (brushes and fonts). "A few" might be hundreds, but if the garbage collector runs every 10 seconds or so that gives you a rate-limited throughput of 10 per second: so your code works fine until you put a real-world heavy load on it.

The garbage collector is there to reclaim memory. It knows what memory you have used. If the memory contains undisposed resources those resources will be properly disposed; but I see that as a second line of defence (in case you didn't dispose them explicitly).

Also about the old previous-installed event handlers for Click I also thought that would screw things up but having ran a dozen iterations of the game and seperate rounds without a problem, it doesn't seem to do so?

If I put a breakpoint in the event handler I can see that it's called multiple times: once the first time, twice the second time, etc. If it's called more than once (e.g. twice) then it sets the vButton text twice, disables it twice, adds two tasks to the waitBtns list. The event handlers also occupy memory and can't be garbage-collected: so if you ran it for long enough (much longer than you've run it) it would run out of memory.

Would you elaborate on what you mean by implementing abstract interfaces?

The simplest version I can think of wouldn't have interfaces.

Have a GameController with the following public API:

// Let players play
void PlayerChoose(Marker playerId, Tuple<int,int> position);
// Let players inspect the current board
// (optional, otherwise players can remember the state of play
// e.g. the Game Form has this state already duplicated in its buttons)
Cell[,] Cells { get; }
// Tell players when the board has changed
delegate void PlayedEventHandler(Marker playerId, Tuple<int,int> position);
event PlayedEventHandler Played;
// Tell players when the game is finished
delegate void FinishedEventHandler(OutcomeType outcome);
event FinishedEventHandler Finished;
// Let players start a new game
void Reset();

An all-human Form-based application can:

  • Have a Game Form like yours
  • Game contains (references) a GameController
  • Game attaches to the Played event handler and updates its UI buttons accordingly
  • Game attaches to its buttons' Clicked event handler and invokes the PlayerChoose method accordingly

A human-versus-AI application can do the same as the above, except:

  • The Game Form is only used by one player
  • There's another, AI class, which:
  • Contains a reference to the GameController
  • Attaches to the Played event handler
  • Chooses its next move and invokes the PlayerChoose method, when the Played event handler tells it that the human has played.

See also:


isn't the point of the managed garbage collector to dispose of objects that aren't used anymore for me?

Yes. The garbage collector might take a while to run, though. For example if you open a file and then let go of the open file without disposing it, the O/S file handle will remain open until the garbage collector reclaims the object; during that time, you can't reopen/reuse the file.

Similarly some resources are in limited supply: you might only be allowed a few SQL connections, or SQL transaction, or GDI objects (brushes and fonts). "A few" might be hundreds, but if the garbage collector runs every 10 seconds or so that gives you a rate-limited throughput of 10 per second: so your code works fine until you put a real-world heavy load on it.

The garbage collector is there to reclaim memory. It knows what memory you have used. If the memory contains undisposed resources those resources will be properly disposed; but I see that as a second line of defence (in case you didn't dispose them explicitly).

Also about the old previous-installed event handlers for Click I also thought that would screw things up but having ran a dozen iterations of the game and seperate rounds without a problem, it doesn't seem to do so?

If I put a breakpoint in the event handler I can see that it's called multiple times: once the first time, twice the second time, etc. If it's called more than once (e.g. twice) then it sets the vButton text twice, disables it twice, adds two tasks to the waitBtns list. The event handlers also occupy memory and can't be garbage-collected: so if you ran it for long enough (much longer than you've run it) it would run out of memory.

Would you elaborate on what you mean by implementing abstract interfaces?

The simplest version I can think of wouldn't have interfaces.

Have a GameController with the following public API:

// Let players play
void PlayerChoose(Marker playerId, Tuple<int,int> position);
// Let players inspect the current board
// (optional, otherwise players can remember the state of play
// e.g. the Game Form has this state already duplicated in its buttons)
Cell[,] Cells { get; }
// Tell players when the board has changed
delegate void PlayedEventHandler(Marker playerId, Tuple<int,int> position);
event PlayedEventHandler Played;
// Tell players when the game is finished
delegate void FinishedEventHandler(OutcomeType outcome);
event FinishedEventHandler Finished;
// Let players start a new game
void Reset();

An all-human Form-based application can:

  • Have a Game Form like yours
  • Game contains (references) a GameController
  • Game attaches to the Played event handler and updates its UI buttons accordingly
  • Game attaches to its buttons' Clicked event handler and invokes the PlayerChoose method accordingly

A human-versus-AI application can do the same as the above, except:

  • The Game Form is only used by one player
  • There's another, AI class, which:
  • Contains a reference to the GameController
  • Attaches to the Played event handler
  • Chooses its next move and invokes the PlayerChoose method, when the Played event handler tells it that the human has played.

See also:

Source Link
ChrisW
  • 12.9k
  • 1
  • 34
  • 76
Loading