我有一个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,显然还有一些我不了解的东西。
那应该怎么做?
答案 0 :(得分:2)
在C#中,async
和await
用于允许代码在完成一些异步过程的同时继续执行。这完全不意味着您正在另一个线程上开始并行处理。
致电时
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());
}
方法将与应用程序的其余部分并行执行。