【问题标题】:I'm having problems with async我遇到了异步问题
【发布时间】:2021-08-31 09:21:15
【问题描述】:

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()
        {
            
            
        }
    }
}

编辑: 里面的代码我已经解释了我尝试了什么以及什么不起作用

【问题讨论】:

  • 删除Task&lt;SocketMessage&gt; SendReceiveAsync(SocketMessage query);这一行,它看起来像一个没有主体的局部函数,并在await SendReceiveAsync之后使用括号来调用该方法。没有括号,这是一个方法组。

标签: c# async-await multiplayer


【解决方案1】:

它应该给你一个错误,因为那是不正确的语法。 SendReceiveAsync 部分应该是什么?

你没有在你的班级的任何地方声明这个函数,所以:

您在类中的某处(函数之外)声明函数

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);
}

您引用了声明此函数的类

也许你尝试使用的这个函数已经在你的一个类成员中声明了。也许在SimpleSocket 类? 如果是这样试试这个:


public async Task ReceiveMessage()
{
    // you still need to get the query from somewhere...
    SocketMessage result = await SML.SendReceiveAsync(query);


    [abbreviated]
}

您尝试做的事情毫无意义,因为您在另一个函数中声明了一个函数,然后尝试从同一个函数内部调用该函数。此外,您正在尝试调用未在任何地方声明的函数。所以看起来你需要在跳到更复杂的东西之前复习一下实际的语法。

【讨论】:

    【解决方案2】:

    您必须更改 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

    【讨论】:

    • 这里出现错误:[C:\programming\Stride 3D\MyGame\MyGame\Net.cs(38,13)]:错误:“await”运算符只能在异步中使用方法。考虑使用“async”修饰符标记此方法并将其返回类型更改为“Task”。 [C:\programming\Stride 3D\MyGame\MyGame\Net.cs(37,21)]:错误:'Net.SendMessage(string)':并非所有代码路径都返回值 [C:\programming\Stride 3D\ MyGame\MyGame\Net.cs(42,36)]:错误:无法等待“方法组”
    • 抱歉,SendMessage(带等待)需要异步,而同步需要返回 void。我改变了我的样本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    相关资源
    最近更新 更多