我遇到异步问题
I'm having problems with async
documentation我正在阅读
写着:public Task<SocketMessage> SendReceiveAsync(SocketMessage query)
在源代码中是:public async Task<SocketMessage> SendReceiveAsync(SocketMessage query){...}
我想了解的是如何调用它以及它是如何工作的。我尝试的任何事情都会出错。
我想做的是从服务器发送和接收消息。我已经为此工作了数周,现在我也一直在阅读 How and when to use ‘async’ and ‘await’ 但我无法让它发挥作用。
这是我设法做到的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Stride.Core.Mathematics;
using Stride.Input;
using Stride.Engine;
using Stride.Engine.Network;
using System.IO;
namespace MyGame
{
public class Net : SyncScript
{
string str = "";
public Stream socket;
public SimpleSocket SS;
public SocketMessage SM;
public SocketMessageLayer SML;
public void Server(){
SML = new SocketMessageLayer(SS, true);
//int port, bool singleConnection, int retryCount = 1
SS.StartServer(21, true, 1);
}
public void Client(){
SML = new SocketMessageLayer(SS, false);
//string address, int port, bool needAck = true
SS.StartClient("127.0.0.1", 21, true);
}
Task<SocketMessage> SendReceiveAsync(SocketMessage query){
//here I need to return somehow as I get error: not all code paths return a value
return query; // Error: Cannot implicitly convert type 'Stride.Engine.Network.SocketMessage' to 'System.Threading.Tasks.Task<Stride.Engine.Network.SocketMessage>'
}
public async Task ReceiveMessage(){
// you still need to get the query from somewhere...
SocketMessage result = await SML.SendReceiveAsync(SM);
//[abbreviated] // if I uncomment this I get: Error: ; expected
//Error: Invalid expression term '}'
}
public override void Start(){
}
public override void Update()
{
}
}
}
编辑:
内部代码我已经解释了我尝试过的和不起作用的
您必须更改 ReceiveMessage,因此编译器并不意味着您要声明一个名为 SendReceiveAsync 的方法。从您发布的文档中,您想在 SocketMessageLayer 上调用它,所以请尝试:
public async Task<SocketMessage> ReceiveMessage()
{
//and now we call await on the task
SocketMessage result = await SML.SendReceiveAsync;
return result;
}
顺便说一下,根据文档 SML.Send 也是异步的,因此您应该重新定义:
public async Task SendMessage(string str){
await SML.Send(str);
}
或者如果你想以同步方式调用它(我不推荐)试试:
public void SendMessage(string str){
SML.Send(str).GetAwaiter().GetResult();
}
见Calling async method synchronously
它给你一个错误,因为它应该是错误的语法。 SendReceiveAsync
部分应该是什么?
您没有在 class 中的任何地方声明该函数,所以:
您在 class 的某处声明函数(在您的函数之外):
Task<SocketMessage> SendReceiveAsync(SocketMessage query)
{
//do logic
}
然后您可以从您的函数中调用它,就像调用任何其他函数一样:
public async Task ReceiveMessage()
{
// still need to provide a query
SocketMessage result = await SendReceiveAsync(query);
//int result = await longRunningTask;
//use the result
//Console.WriteLine(result);
}
您引用了声明此函数的class:
也许您尝试使用的这个函数已经在您的 class 成员中声明了。也许在 SimpleSocket
class 中?
如果是这样,试试这个:
public async Task ReceiveMessage()
{
// you still need to get the query from somewhere...
SocketMessage result = await SML.SendReceiveAsync(query);
[abbreviated]
}
您尝试做的事情毫无意义,因为您是在另一个函数内声明一个函数,然后试图从同一个函数内调用该函数。此外,您正试图调用一个未在任何地方声明的函数。所以看起来你需要在跳到更复杂的东西之前复习一下实际的语法。
documentation我正在阅读
写着:public Task<SocketMessage> SendReceiveAsync(SocketMessage query)
在源代码中是:public async Task<SocketMessage> SendReceiveAsync(SocketMessage query){...}
我想了解的是如何调用它以及它是如何工作的。我尝试的任何事情都会出错。
我想做的是从服务器发送和接收消息。我已经为此工作了数周,现在我也一直在阅读 How and when to use ‘async’ and ‘await’ 但我无法让它发挥作用。
这是我设法做到的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Stride.Core.Mathematics;
using Stride.Input;
using Stride.Engine;
using Stride.Engine.Network;
using System.IO;
namespace MyGame
{
public class Net : SyncScript
{
string str = "";
public Stream socket;
public SimpleSocket SS;
public SocketMessage SM;
public SocketMessageLayer SML;
public void Server(){
SML = new SocketMessageLayer(SS, true);
//int port, bool singleConnection, int retryCount = 1
SS.StartServer(21, true, 1);
}
public void Client(){
SML = new SocketMessageLayer(SS, false);
//string address, int port, bool needAck = true
SS.StartClient("127.0.0.1", 21, true);
}
Task<SocketMessage> SendReceiveAsync(SocketMessage query){
//here I need to return somehow as I get error: not all code paths return a value
return query; // Error: Cannot implicitly convert type 'Stride.Engine.Network.SocketMessage' to 'System.Threading.Tasks.Task<Stride.Engine.Network.SocketMessage>'
}
public async Task ReceiveMessage(){
// you still need to get the query from somewhere...
SocketMessage result = await SML.SendReceiveAsync(SM);
//[abbreviated] // if I uncomment this I get: Error: ; expected
//Error: Invalid expression term '}'
}
public override void Start(){
}
public override void Update()
{
}
}
}
编辑: 内部代码我已经解释了我尝试过的和不起作用的
您必须更改 ReceiveMessage,因此编译器并不意味着您要声明一个名为 SendReceiveAsync 的方法。从您发布的文档中,您想在 SocketMessageLayer 上调用它,所以请尝试:
public async Task<SocketMessage> ReceiveMessage()
{
//and now we call await on the task
SocketMessage result = await SML.SendReceiveAsync;
return result;
}
顺便说一下,根据文档 SML.Send 也是异步的,因此您应该重新定义:
public async Task SendMessage(string str){
await SML.Send(str);
}
或者如果你想以同步方式调用它(我不推荐)试试:
public void SendMessage(string str){
SML.Send(str).GetAwaiter().GetResult();
}
见Calling async method synchronously
它给你一个错误,因为它应该是错误的语法。 SendReceiveAsync
部分应该是什么?
您没有在 class 中的任何地方声明该函数,所以:
您在 class 的某处声明函数(在您的函数之外):
Task<SocketMessage> SendReceiveAsync(SocketMessage query)
{
//do logic
}
然后您可以从您的函数中调用它,就像调用任何其他函数一样:
public async Task ReceiveMessage()
{
// still need to provide a query
SocketMessage result = await SendReceiveAsync(query);
//int result = await longRunningTask;
//use the result
//Console.WriteLine(result);
}
您引用了声明此函数的class:
也许您尝试使用的这个函数已经在您的 class 成员中声明了。也许在 SimpleSocket
class 中?
如果是这样,试试这个:
public async Task ReceiveMessage()
{
// you still need to get the query from somewhere...
SocketMessage result = await SML.SendReceiveAsync(query);
[abbreviated]
}
您尝试做的事情毫无意义,因为您是在另一个函数内声明一个函数,然后试图从同一个函数内调用该函数。此外,您正试图调用一个未在任何地方声明的函数。所以看起来你需要在跳到更复杂的东西之前复习一下实际的语法。