TFTP 앱에서 C#을 올바르게 "사용"하고 있는지 확실하지 않습니다.

StackOverflow https://stackoverflow.com//questions/25070454

  •  26-12-2019
  •  | 
  •  

문제

나는 사용하려고 이것 내 Windows C# 형식으로 미리 만들어진 C# tftp 서버 앱입니다.훌륭하게 작동하는 저자의 서버 예제에서 그는 콘솔 앱을 사용합니다.그의 콘솔 예제를 내 양식 앱으로 포팅하려고 하면 작동하지 않으며(오류도 없고 연결되지도 않음) 내 문제가 "using" 문에 있는 것 같습니다.

using (var server = new TftpServer())
{
    server.OnReadRequest += new TftpServerEventHandler(server_OnReadRequest);
    server.OnWriteRequest += new TftpServerEventHandler(server_OnWriteRequest);
    server.Start();
    Console.Read();
}

내가 제대로 이해한 것인지는 모르겠지만 나는 그 말을 믿는다. Console.Read() 앱이 종료되지 않도록 차단합니다.이 경우 양식 앱으로 동등한 것을 어떻게 구현합니까?나는 "사용"에 대해 머리를 숙일 수 없습니다.죄송합니다. 저는 C#을 처음 접했습니다.

도움이 되었습니까?

해결책

Windows Forms는 사용자가 명시적으로 닫을 때까지 항상 열려 있습니다.항상 사용자 입력을 위해 메시지 대기열을 읽는 스레드가 있으므로 제한되지 않은 콘솔 응용 프로그램과 같은 방식으로 종료되지 않습니다.Windows Forms에서는 콘솔 앱에서보다 멀티스레딩 및 동시성에 대해 좀 더 걱정해야 합니다.대부분 자연적으로 발생하지만 항상 그런 것은 아닙니다.

그 때문에 실제로는 다음과 같은 것을 사용할 수 없습니다. Console.Read() 집행을 보류하다 using 사용자가 요청할 때까지 폐기됩니다.그렇게 하면 양식이 응답하지 않는 것처럼 보일 것입니다.

그러나 당신은 운이 좋다!ㅏ using C#의 블록은 호출을 기억하기 위한 구문 설탕에 지나지 않습니다. IDisposable.Dispose() 개체 작업을 마친 후.따라서 Forms 프로젝트에서 이에 상응하는 작업은 server 클래스 전체 필드의 개체를 호출한 다음 server.Dispose() 에, 말하자면, Button.Click 이벤트.물론 그것은 단지 예일 뿐입니다.당신은 또한 그것을 할 수 있습니다 Form.Closing 그게 더 적절하다고 느껴진다면요.

높은 수준에서는 다음과 같은 작업을 수행하고 싶습니다.

  1. 양식 클래스에서 필드 선언 TftpServer server;.
  2. 등록하다 Load 이벤트 및 귀하에게 필요한 모든 것 server 생성자에서 작동합니다.
  3. 당신의 server 필드 Form_Load 이벤트.
  4. 사용 server당신이 보는 바와 같이 의 사건은 당신의 생애 동안 매우 적합합니다. Form.동시성에 대해 걱정할 수도 있고 필요하지 않을 수도 있지만 이는 다른 질문의 문제입니다.
  5. 부르다 server.Dispose() 양식에 Dispose 이벤트.

본질적으로,

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;
        }
    }
}

다른 팁

문제는 서버를 폐기하는 것이 무엇인지 폐기하는 것입니다.유사한 설탕을 사용하여 사용하는 것을 명심하십시오.다음 두 가지 코드 덩어리가 [실질적으로]

var foo = new Foo();
try
{
   foo.Do();
}
finally
{
   foo.Dispose();
}
.


using (var foo = new Foo())
{
   foo.Do();
}
.

콘솔 앱에서 종료되지만 양식 앱에서 주 스레드를 차단하는 것이 좋습니다.문제는 일종의 차단 작업을 수행하여 사용 내부에서 스레드를 보관해야한다는 것은 아닙니다.그건 나쁠 것이고, 행동은 양식 앱을 잠그게됩니다.문제는 사용하고 싶지 않습니다.서버를 시작한 다음 나중에, 응용 프로그램 종료시 또는 중지 클릭에서 나중에 새로 만들고 싶습니다.

In a console application your TftpServer instance is listening until the thread exits which is only after a key is pressed which is detected by Console.Read()

In your forms app that Console.Read() isn't waiting around and so the using block finishes and that causes your server instance to fall out of scope.

So you are not exactly misusing the using but rather the intended use is not helping you at all. Take a look at using the task parallel library to let some background tasks run asynchronously.

A small note that also doubles as an answer, you could use a using block here, you just put it in your main function:

...(make your form and stuff) 
using (var server = new TftpServer())
{
   server.OnReadRequest += new TftpServerEventHandler(server_OnReadRequest);
   server.OnWriteRequest += new TftpServerEventHandler(server_OnWriteRequest);
   server.Start();
   Application.Run(yourFormHere); //This blocks until the form is closed
}

Another option I forgot to mention is overriding Dispose in your Form. You probably want to do this. With this option you're guaranteed your server will be disposed (bar some event that would prevent it from being disposed either way [ie. being out of memory])

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top