Search code examples
c#templatesasync-awaitstride

problem understanding the template in c# and function


the documentation network and the most importantly documentation: SocketMessageLayer

in SocketMessageLayer there is function which I don't know how to call: public void AddPacketHandler<T>(Func<T, Task> asyncHandler, bool oneTime = false)

and this is how I was trying to call it:

    string str = "example";
    public SimpleSocket SS = new SimpleSocket();
    public SocketMessageLayer SML;
    
    
    
    public void Server(){
        //int port, bool singleConnection, int retryCount = 1
        SS.StartServer(21, false, 1);
        SML = new SocketMessageLayer(SS, true);
    }
    public void Client(){
        //string address, int port, bool needAck = true
        SS.StartClient("127.0.0.1", 21, true);
        SML = new SocketMessageLayer(SS, false);
    }
    
    
    
    public async Task SendMessage(string str){
        //public void AddPacketHandler<T>(Func<T, Task> asyncHandler, bool oneTime = false)
        await SML.AddPacketHandler<string>(SomeFunction("ClientSendToServer", await SML.Send(str) ), false  );
        //await SML.Send(str);
        
    }
    
    
    public void SomeFunction(string s, Task Tas){
        str = s;
    }

the problem is Argument 2: cannot convert from 'void' to 'System.Threading.Tasks.Task' in Send Message

what I'm trying to do is send message to server or from server to client. and I have problem understanding the basics.


Solution

  • There are number of issues here.

    AddPacketHandler expects a Func<T, Task> delegate as it's first parameter, but you are invoking SomeFunction rather than passing it as a delegate.

    This means that you are attempting to pass the return value of SomeFunction i.e. void, which isn't allowed, hence the compilation error.

    Furthermore, Func<T, Task> is a delegate that accepts a single argument of type T and returns a Task.

    Your SomeFunction method accepts two arguments of type T and Task and returns void, so it cannot be converted into a Func<T, Task> and cannot be passed as the first parameter.

    What you could do is change the signature of SomeFunction to this:

    public Task SomeFunction(string s)
    {
        str = s;
        return Task.CompletedTask;
    }
    

    Which can be passed as follows:

    public async Task SendMessage(string str)
    {
        SML.AddPacketHandler<string>(SomeFunction, false);
        await SML.Send(str);        
    }
    

    And you probably want to pass "ClientSendToServer" to SendMessage rather than hardcoding it into that method:

    await SendMessage("ClientSendToServer");