victor
victor

Reputation: 11

collect output from Task.Whenall to a list/data-type

I have the following c# code where i am sending a series of requests and reponses

public static async Task AuthenticateQvpx2()
{
    var handshake = new Handshake();
    foreach (var request in handshake.AutheticateStrings)
    {
        var buffer = _encoder.GetBytes(request);
        await Task.WhenAll(Receive(_webSocket), Send(_webSocket, buffer));
    }
}

The async functions Send and Receive, has the following code.

await webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);

var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

I wish to collect the requests and responses into an array/ any form of data type.

I having trouble as I am not particularly sure of what i should do next?

Upvotes: 0

Views: 439

Answers (3)

Stephen Cleary
Stephen Cleary

Reputation: 457207

I wish to collect the requests and responses

It's kind of odd to collect the requests, as that data is already right there (in the buffer variable).

Assuming you meant that you just need the response, you can do that using await:

public static async Task AuthenticateQvpx2()
{
  var handshake = new Handshake();
  foreach (var request in handshake.AutheticateStrings)
  {
    var buffer = _encoder.GetBytes(request);
    var receiveTask = Receive(_webSocket);
    await Task.WhenAll(receiveTask, Send(_webSocket, buffer));
    var response = await receiveTask;
  }
}

Upvotes: 1

Yarl
Yarl

Reputation: 798

Try something like

ConcurrentDictionary<Guid, (System.Byte[], WebSocketReceiveResult)> x = new ConcurrentDictionary<Guid, (byte[], WebSocketReceiveResult)>();

Generate GUID in your foreach a pass it to your methods:

foreach (var request in handshake.AutheticateStrings)
{
  var buffer = _encoder.GetBytes(request);
  var guid = Guid.NewGuid();
  await Task.WhenAll(Receive(_webSocket, guid), Send(_webSocket, buffer, guid));
}

Then you can work with dictionary from within your Receive and Send methods in natural way.

void Send(WebSocket webSocket, byte[] buffer, Guid guid)
{
  x.GetOrAdd(guid, new ValueTuple<System.Byte[], WebSocketReceiveResult>(buffer, null));
  await webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None)
}

void Receive(WebSocket webSocket, Guid guid)
{
  var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
  x[guid].Item2 = result;
}

Upvotes: 0

codernr
codernr

Reputation: 121

Not sure based on your snippets what type of Tasks your Send and Receive return but generally you can get your results from multiple tasks after using Task.WhenAll using LINQ this way:


var handshake = new Handshake();

List<Task<WebsocketReceiveResult>> tasks = newList<Task<WebsocketReceiveResult>>();

foreach (var request in handshake.AutheticateStrings)
{
    var buffer = _encoder.GetBytes(request);
    tasks.Add(webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None));
}

await Task.WhenAll(tasks);

var resultArray = tasks.Select(t => t.Result).ToArray();

Upvotes: 0

Related Questions