как сделать TCP-сервер в xamarin, который не замораживает мое приложение - PullRequest
0 голосов
/ 28 сентября 2018

У меня есть TCP-сервер с методом запуска, похожим на:

public async Task Start()
{
    using (Canceler.Token.Register(() => listener.Stop()))
    {
        try
        {
            listener.Start();
            var tcpClient = await listener.AcceptTcpClientAsync();
            var clientStream = tcpClient.GetStream();
            while(!CloseAll)
            {
                while (!clientStream.DataAvailable)
                {
                    if (CloseAll)
                    {
                        break;
                    }
                }
                Byte[] bytes = new Byte[tcpClient.Available];
                clientStream.Read(bytes, 0, bytes.Length);
                String data = Encoding.UTF8.GetString(bytes);
                Debug(data);
            } 
        }
        catch (Exception exc)
        {
            Debug(exc.Message);
            Canceler.Token.ThrowIfCancellationRequested();
            throw;
        }
    }
}

А затем класс связи, который обрабатывает его, выглядит так:

internal async void Init()
{
    DebugMessage("initializing gameBrain");
    TCP = new TCPController();
    TCP.newDebugMessage += Debug;
    await TCP.Start();
}

И на самом верху, ву нас есть страница:

public MainPage(GameBrain _brain)
{
    InitializeComponent();
    Brain = _brain;
    Brain.newMessageToUI += NewMessageFromBrain;
    Brain.Init();
}

Я запустил вещь, и она работает в начале.Пользовательский интерфейс отзывчив (я добавил кнопку с displayAlert для тестирования) Я заметил, что система зависает после подключения TCP-клиента.Во внутреннем времени запуска, но ... я думал, что это ожидалось!

Я думал, что запуск будет выполняться в другом потоке, пока приложение get освободится от него.Честно говоря, я привык к фоновым специалистам, но я перехожу оттуда к Задачам, и есть определенно что-то, чего я не получаю.

Как это сделать?

1 Ответ

0 голосов
/ 28 сентября 2018

В C # async и await используются для того, чтобы код продолжал выполняться, пока выполняется какой-то асинхронный процесс.Это вовсе не означает, что вы запускаете параллельный процесс в другом потоке.

Когда вы вызываете это:

internal async void Init()
{
    (..)
    await TCP.Start();
}

Вы просто говорите среде выполнения, что TCP.Start() в конечном итогеиметь точку в выполнении, где запускается какой-то асинхронный процесс (например, HTTP-запрос к третьей стороне) и что ему разрешено выполнять код после TCP.Start() вместо ожидания завершения TCP.Start(), как в обычном методе C #обработано.

Если вы хотите, чтобы TCP.Start() выполнялся параллельно, вы должны создать новый Task, в котором вы вызываете метод, как показано в следующем коде (возможно, я ошибся в правильном синтаксисе)

internal async void Init()
{
    (..)
    Task.Run(async () => await TCP.Start());
}

Теперь метод TCP.Start() будет выполняться параллельно с остальной частью приложения.

Подробнее об асинхронности и ждать здесь

...