Windows Forms will always remain open until they're explicitly closed by the user. They always have a thread reading the message queue for user input, so they won't exit the same way an unrestrained console application will. In Windows Forms, we have to worry a bit more about multithreading and concurrency than we would in console apps. It mostly comes naturally, but not always.
Because of that, you can't really use an equivalent to Console.Read()
to hold off execution of the using
disposal until the user requests it. If you did, your form would simply appear unresponsive.
However, you're in luck! A using
block in C# is nothing more than syntactic sugar for remembering to call IDisposable.Dispose()
after you're done with an object. So the equivalent to this in a Forms project could just be storing the server
object in a class-wide field, then calling server.Dispose()
on, say, a Button.Click
event. That's, of course, just an example. You could also do it on Form.Closing
if that felt more appropriate.
High-level, you want to do something like this:
- Declare a field in your form class
TftpServer server;
.
- Register a
Load
event and whatever you need for your server
to function in your constructor.
- Open your
server
field in the Form_Load
event.
- Use the
server
's events as you see so fit during the life of your Form
. You may or may not have to worry about concurrency, but that's a matter for another question.
- Call
server.Dispose()
in the form's Dispose
event.
In essence,
class main : Form
{
private TftpServer server;
public main()
{
InitializeComponent();
this.Load += main_Load;
server = new TftpServer();
server.OnReadRequest += new TftpServerEventHandler(server_OnReadRequest);
server.OnWriteRequest += new TftpServerEventHandler(server_OnWriteRequest);
}
private void main_Load(object sender, EventArgs e)
{
server.Start();
}
private void server_OnReadRequest(/* I wasn't sure of the arguments here */)
{
// use the read request: give or fetch its data (depending on who defines "read")
}
private void server_OnWriteRequest(/* I wasn't sure of the arguments here */)
{
// use the write request: give or fetch its data (depending on who defines "write")
}
protected override void Dispose(bool disposing)
{
if (server != null) // since Dispose can be called multiple times
{
server.Dispose();
server = null;
}
}
}