#c# #templates #async-await #stride
Вопрос:
сеть документации и самая важная документация: SocketMessageLayer
в SocketMessageLayer есть функция, которую я не знаю, как вызвать: public void AddPacketHandler<T>(Func<T, Task> asyncHandler, bool oneTime = false)
и вот как я пытался это назвать:
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;
}
проблема Argument 2: cannot convert from 'void' to 'System.Threading.Tasks.Task'
в отправке сообщения
то, что я пытаюсь сделать, — это отправить сообщение на сервер или с сервера на клиент. и у меня проблемы с пониманием основ.
Комментарии:
1. спасибо, но если я это сделаю, я получу:
cannot convert from 'void' to 'System.Action<string>'
Ответ №1:
Здесь есть ряд проблем.
AddPacketHandler
ожидает Func<T, Task>
делегата в качестве первого параметра, но вы вызываете SomeFunction
его, а не передаете как делегат.
Это означает, что вы пытаетесь передать возвращаемое значение SomeFunction
т. е. void, что недопустимо, следовательно, ошибка компиляции.
Кроме того, Func<T, Task>
является делегатом, который принимает один аргумент типа T
и возвращает a Task
.
Ваш SomeFunction
метод принимает два аргумента типа T
и Task
и возвращает void
, поэтому он не может быть преобразован в a Func<T, Task>
и не может быть передан в качестве первого параметра.
Что вы могли бы сделать, так это изменить подпись SomeFunction
на эту:
public Task SomeFunction(string s)
{
str = s;
return Task.CompletedTask;
}
Который может быть передан следующим образом:
public async Task SendMessage(string str)
{
SML.AddPacketHandler<string>(SomeFunction, false);
await SML.Send(str);
}
И вы, вероятно, захотите перейти "ClientSendToServer"
к SendMessage
этому методу, а не жестко его кодировать:
await SendMessage("ClientSendToServer");
Ответ №2:
Первый и самый важный: почему вы должны вызывать AddPacketHandler?
Глядя на это, обработчик пакетов не является обязательным, поэтому вы не можете добавлять его, если он вам не нужен, хотя для регистрации обработчика пакетов вы можете сделать это множеством способов, вот три примера:
Пример 1
public class Program
{
private static List<Func<object, Task>> _handlers = new List<Func<object, Task>>();
public static async Task Main(string[] args)
{
// you handler code goes here
Func<string, Task> func = (str) => Task.Run(() => Console.WriteLine(str));
AddPacketHandler(func);
await _handlers[0]("foo");
}
public static void AddPacketHandler<T>(Func<T, Task> asyncHandler)
{
_handlers.Add((obj) => asyncHandler((T)obj));
}
}
Пример 2
public class Program
{
private static List<Func<object, Task>> _handlers = new List<Func<object, Task>>();
public static async Task Main(string[] args)
{
// you can create your handler here
AddPacketHandler<string>(
(str) =>
{
return Task.Run(() => Console.WriteLine(str));
});
await _handlers[0]("foo");
}
public static void AddPacketHandler<T>(Func<T, Task> asyncHandler)
{
_handlers.Add((obj) => asyncHandler((T)obj));
}
}
Пример 3
public class Program
{
private static List<Func<object, Task>> _handlers = new List<Func<object, Task>>();
public static async Task Main(string[] args)
{
AddPacketHandler<string>(SomeFunction);
await _handlers[0]("foo");
}
// you handler code goes here
private static Task SomeFunction(string s)
{
return Task.Run(() => Console.WriteLine(s));
}
public static void AddPacketHandler<T>(Func<T, Task> asyncHandler)
{
_handlers.Add((obj) => asyncHandler((T)obj));
}
}
Сам дескриптор будет вызван библиотекой здесь
Этот код основан на исходном коде, который содержится в документах, о которых вы сообщили, всегда здорово взглянуть на это и посмотреть, что на самом деле делает функция, если вы столкнетесь с подобной ситуацией.