I am creating a Chatting application in a C# console app and just starting to learn about async tasks rather than just multi-threading which from my understanding is sort of outdated and better off using async.
I am using Microsoft's official documentation on sockets as a sort of guide to my own application because they use asynchronous programming but am getting an error.
Here is the code where I get the error:
private async Task handleClientsAsync(Socket server)
{
Byte[] _buffer = new Byte[1024];
Socket client = await server.AcceptAsync();
while (true)
{
bool received = await client.ReceiveAsync(_buffer, SocketFlags.None); //This is the line with the error
}
}
The error is: "No overload for method 'ReceiveAsync' takes '2' arguments." This confuses me because, on Microsoft's official documentation, they pass through the same parameters.
Any help is much appreciated :)
CodePudding user response:
The error is a bit misleading. While there are no overloads that take 2 arguments, there are extension methods that do.
Some of the overloads for ReceiveAsync()
were moved to extension methods between .NET 4.7 and .NET 4.7.1, in the System.Net.Sockets.SocketTaskExtensions
class. As long as you have using System.Net.Sockets;
at the top of your file, you can use those extension methods.
So why doesn't it work? Well, there never was an overload that accepted a plain byte array. But there was an overload that accepted Memory<Byte>
and the Memory<T>
class has an operator to implicitly cast.
That version of the overload was not moved to the extension methods. The only equivalent one accepts ArraySegment<Byte>
, and ArraySegment<T>
has no implicit casting operator. So you have to create the ArraySegment<Byte>
yourself.
Although, even after you fix that, you'll get a compiler error warning that you can't implicitly cast an int
to bool
, since ReceiveAsync()
has always returned an int
.
You can change that line to this:
var received = await client.ReceiveAsync(new ArraySegment<byte>(_buffer), SocketFlags.None); //This is the line with the error
The ArraySegment<T>
struct does not copy the underlying array. It's just a way to refer to a section of an array. If you do not pass a range to the constructor, then it refers to the whole array.
CodePudding user response:
The function signature was changed between releases of .NET
In .Net 4.8 ReceiveAsync()
has one parameter only:
public bool ReceiveAsync (System.Net.Sockets.SocketAsyncEventArgs e);
In .Net 7 ReceiveAsync()
has one or two parameters, but no overload is suitable for your call.