如何在xamarin中制作不会冻结我的应用的TCP服务器

时间:2018-09-28 11:23:16

标签: xamarin tcplistener

我有一个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();
}

我跑了东西,一开始就起作用。 UI是响应式的(我添加了带有displayAlert的按钮以进行测试) 我注意到TCP客户端连接后系统冻结。在开始阶段的内部,但是...我认为这是预期的!

我以为Start将在释放应用程序的同时在不同的线程中运行。老实说,我已经习惯了背景工作人员,但我正从那里移到Tasks,显然还有一些我不了解的东西。

那应该怎么做?

1 个答案:

答案 0 :(得分:2)

在C#中,asyncawait用于允许代码在完成一些异步过程的同时继续执行。这完全不意味着您正在另一个线程上开始并行处理。

致电时

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

您只是对运行时说,TCP.Start()最终将在执行过程中启动一些异步过程(例如对第三方的HTTP请求),并允许在{之后执行代码。 {p}而不是像对待普通的C#方法那样等待TCP.Start()完成。

如果您希望TCP.Start()并行运行,则应创建一个新的TCP.Start(),在其中调用该方法,如下面的代码所示(我可能没有采用正确的语法)

Task

现在internal async void Init() { (..) Task.Run(async () => await TCP.Start()); } 方法将与应用程序的其余部分并行执行。

Read more on async and await here