Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to wait for a transmission's completion? #9

Open
artshade opened this issue Jun 1, 2020 · 3 comments
Open

How to wait for a transmission's completion? #9

artshade opened this issue Jun 1, 2020 · 3 comments

Comments

@artshade
Copy link

artshade commented Jun 1, 2020

Dear Developer,

Thank you for this project.
Although, for example, we have a code where:

... // Somehere in AsyncTCPClient's initialization
ReceivedCallback = (c, count) =>
{
    Console.WriteLine("2");
    response = c.ByteBuffer.Dequeue(count);
    if (responseLength + count <= int.MaxValue)
        responseLength += count;
    Console.WriteLine("3, responseLength = {0}", responseLength );
    return Task.CompletedTask;
}
...
ct1 = new CancellationTokenSource(1000); // 1000ms for a request timeout
t1 = this.asyncTCPClient.Send(new ArraySegment<byte>(data, 0, data.Length), ct1.Token);
if (ct1.IsCancellationRequested) // If connection or any answer timeout
{
    Console.WriteLine("Timeout");
}
else
{
    ct1 = new CancellationTokenSource(1000); // 1000ms for a response timeour
    Console.WriteLine("1");
    t1 = this.asyncTCPClient.WaitAsync(ct1.Token); // Wait for any response available
    Console.WriteLine("4, responseLength = {0}", responseLength);
}

And the output would be:

    1
    4, responseLength = 0 // It seems that WaitAsync does not wait while ByteBuffer dequeues.
    2
    3, responseLength = 41

Is it possible to force WaitAsync to wait while the full transaction would be completed?

@ygoe
Copy link
Owner

ygoe commented Jun 2, 2020

The AsyncTcpClient.WaitAsync method waits for data to be available in the receive buffer. It doesn't wait until you processed it. If you want that, you should set a signal when you're done, at the end of your ReceivedCallback handler. You could use a TaskCompletionSource for that.

@artshade
Copy link
Author

artshade commented Jun 2, 2020

The AsyncTcpClient.WaitAsync method waits for data to be available in the receive buffer. It doesn't wait until you processed it. If you want that, you should set a signal when you're done, at the end of your ReceivedCallback handler. You could use a TaskCompletionSource for that.

Thank you, but how to wait for TaskCompletionSource if WaitAsync returns immediately when any data was received?

Currently, this one works:

ct1 = new CancellationTokenSource(1000);
this.asyncTCPClient.WaitAsync(ct1.Token); // Wait for any response available
if (!ct1.IsCancellationRequested) // If received something
{
    ct1 = new CancellationTokenSource(1000);
    while (responseLength != expectedResponseLength) // Wait for all requested data transferred
    {
        if (ct1.IsCancellationRequested) // If full data transfer timed out
        {
            fullDataTimeout= true; // Set flag of data's timeout
            break;
        }
        Thread.Sleep(100); // To escape a busy loop issue
    }
}
else
    connectionTimeout= true; // Set flag of connection's timeout

It works. However, it seems like it is not the best solution. Sorry, but what did you mean by TaskCompletionSource?

@ygoe
Copy link
Owner

ygoe commented Jun 2, 2020

You're calling AsyncTcpClient.WaitAsync and expect to wait until you finished processing the received data. That's the wrong method. You're waiting for new data to be available. Instead of this you should wait for your own event.

TaskCompletionSource<T> is a class that lets you create tasks you can wait on. Later, you can explicitly complete these tasks "from the outside", by calling a method like TrySetResult. Whoever waits for this task can then continue. It's to common pattern to asynchronously wait for something you do. It's also used in AsyncTcpClient.WaitAsync to wait for either new data or a closed connection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants