0

이 질문에는 이미 답변이 있습니다.

나는 배우려고 노력하고 있어요async/await그래서 이것은 바보 같은 질문처럼 들릴지 모르겠지만, 나는 현재 기본 TCP 서버에서 작업 중이며async/await여러 연결을 처리하는 수동 스레딩 대신.

안에NetworkClient클래스 나는 다음과 같은 메서드가 있습니다 :

    public async Task Start()
    {
        using (var reader = new StreamReader(_socket.GetStream()))
        {
            while (_server.IsRunning)
            {
                try
                {
                    var content = await reader.ReadLineAsync().ConfigureAwait(false);
                    if (content == null)
                    {
                        Console.WriteLine("Client {0} disconnected", _id);
                        return;
                    }

                    Console.WriteLine("Client {0} wrote: {1}", _id, content);
                }
                catch (IOException)
                {
                    Console.WriteLine("Client {0} disconnected", _id);
                    return;
                }
            }
        }
    }

클라이언트 연결을 수신 대기하는 내 루프에는 다음 코드가 포함됩니다.

    private void ListenForClients()
    {
        var numClients = 0;
        while (IsRunning)
        {
            var tcpClient = _listener.AcceptTcpClient();
            var netClient = new NetworkClient(this, tcpClient, numClients);
            netClient.Start();

            Console.WriteLine("Client {0} Connected", numClients);
            numClients++;
        }
    }

이것은 예상대로 작동하며 여러 텔넷 연결을 통해 동시에 서버에 연결하여 메시지를 보낼 수 있습니다. 그러나 resharper는 내가awaitnetClient.Start();그렇지 않으면 차단되지 않기 때문입니다. 그러나, 나는 그것을 차단하고 싶지 않아!

Resharper가 나에게 이런 경고를하고 있다는 사실 때문에 내가async/await시스템이 잘못되었습니다. Resharper가 왜 내가 추가하길 원하니?await이 코드 라인에이 작업을 수행하는 올바른 방법은 무엇입니까?netClient.Start();~하다아니가입에서 다른 tcp 연결을 차단 하시겠습니까?


2 답변


3

그러나 resharper는 netClient.Start ()에 기다림을 추가해야한다고 알려줍니다. 그렇지 않으면 차단되지 않기 때문입니다. 그러나, 나는 그것을 차단하고 싶지 않아!

ReSharper는 대개 오류이므로이 상황에 대해 경고합니다.

귀하의 경우, 귀하는private Task자신의 타입을 나타내는 멤버 인Start메소드를 호출하고await그것:

startTask = netClient.Start();

이렇게하면 경고가 표시되지 않아야하며Start메소드는 그것이 던지는 예외를 빠져 나오고 종료합니다.


0

당신Start메서드는 실제로 비동기식이 아닙니다. 연결이 동 기적으로 발생하기를 기다리고 비동기 적으로 데이터를 읽는 것처럼 보입니다. 그 결과 코드가ListenForClients실제로는 예상대로 작동합니다.Start전에 끝나다Console.WriteLine(그래서 그것은 정확한 텍스트를 출력합니다) 비동기 부분은 결과를 기다리는 사람없이 스스로 실행됩니다.

이 코드는 기본적으로 "connect + fire 및 데이터 읽기 처리를위한 새 스레드 잊기"와 동일합니다.

async/await비동기 작업을 사용하여 순차 코드를 작성해야 할 때 유용합니다. 실제로 병렬 작업이 필요합니다. 다른 리스너를 여러 개 시작하는 것이 좋습니다. 각 청취자에 대한 코드는await- 훨씬 더 사용하기 쉬운 이벤트를 가진 여러 상태 (또는 더 나쁜 EndSend / SendReceive ...)가 아닌 루프에서 읽기 / 쓰기 대기를 기다립니다.


  • 이해할 수 있는지 확실하지 않습니다. 나의Start메서드는 클라이언트를 동 기적으로 검색하기위한 것이지만 일단 클라이언트가 연결되면 해당 클라이언트의 데이터를 비동기 적으로 기다려야합니다. 그게 내가 가진 것과 작동하는 것입니다. resharper가 나를 원해서 문제는await netClient.Start();그런 다음 클라이언트의 새로운 입력을 기다릴 때 동 기적으로 차단하고 새로운 tcp 클라이언트를 허용하지 않습니다 - KallDrexx
  • @KallDrexx에 의해awiat~하는async함수가 깨져 보이는 코드를 작성하는 중입니다. 코드가 왜 문제인지 설명하는 코드에 절반 페이지 주석을 달아야합니다. 시작을 2 개의 함수로 나누고 새로운 스레드에서 명시 적으로 읽기를 시도하십시오. 참고 : 귀하는 " 동기식 " 2 개의 의미 - 하나의 "현재 스레드에서 블로킹 대기" (동작의 첫 번째 부분이 어떻게 동작하는지) 및 다른 "기능 내의 코드는 동작이 잠재적으로 스레드를 차단하지 않고 완료 될 때까지 그 지점을 지나서 이동하지 않습니다" (방법await행동). - Alexei Levenkov

연결된 질문


관련된 질문

최근 질문