简体   繁体   中英

How can I receive data by a tcp socket in a parallel Task in C#?

I'm writing a client program in a UWP application, which receive data through a TCP socket from a server which send data periodically to this client. I'm meeting a problem that I want to receive data through a Task like below, which read data in a loop using the LoadAsync method. As a result, I need to use await before the method and async for this Task. As I create the StreamSocket and call the Task in another method, the ListenTcpClient Task returns after the LoadAsync() method, and data isn't received and showed in the next steps. Can you tell me how can I receive data from a TCP socket while keep UI thread and other thread working on other things? Thank you.

public async Task ListenTcpClient(StreamSocket clientTcpSocket)
{
    while(clientTcpSocket!=null)
    {
        using (DataReader reader = new DataReader(clientTcpSocket.InputStream))
        {
            await reader.LoadAsync(sizeof(int));
            int fdToReadRcv = reader.ReadInt32();
            byte[] bs = BitConverter.GetBytes(fdToReadRcv);
            Array.Reverse(bs);
            int fdToRead = BitConverter.ToInt32(bs, 0);
            Debug.WriteLine(fdToRead);
            StartButton1.Content = fdToRead;
        }
    }
}

private async void Button_Click(object sender, RoutedEventArgs e)
{
    clientTcpSocket = new StreamSocket();
    try
    {// create the socket
        await clientTcpSocket.ConnectAsync(new HostName(ip), tcpPort);
        using (DataReader reader = new DataReader(clientTcpSocket.InputStream))
        {
            await reader.LoadAsync(sizeof(int));
            int fdToReadRcv = reader.ReadInt32();
            byte[] bs = BitConverter.GetBytes(fdToReadRcv);
            Array.Reverse(bs);
            int fdToRead = BitConverter.ToInt32(bs,0);
            Debug.WriteLine(fdToRead);
        }
        using (DataWriter writer = new DataWriter(clientTcpSocket.OutputStream))
        {
            writer.WriteString(String.Format("Client Start"));
            await writer.StoreAsync();
        }
        timer.Start();
        ListenTcpClient(clientTcpSocket);
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
    //then do something else while the client socket is receiving data
}

As long as the Task 's are independent from one another, you can run it in parallel by using Task.WhenAll(...)

private async void Button_Click(object sender, RoutedEventArgs e)
{
        // generate a create socket task
        var createSocketTask = CreateSocket();

        // create 'do something else' task
        var doSomethingElseTask = DoSomethingElse();

        // run both tasks in parallel
        await Task.WhenAll(createSocketTask, doSomethingElseTask);
}

private async Task CreateSocket()
{
    clientTcpSocket = new StreamSocket();
    try
    {// create the socket
        await clientTcpSocket.ConnectAsync(new HostName(ip), tcpPort);
        using (DataReader reader = new DataReader(clientTcpSocket.InputStream))
        {
            await reader.LoadAsync(sizeof(int));
            int fdToReadRcv = reader.ReadInt32();
            byte[] bs = BitConverter.GetBytes(fdToReadRcv);
            Array.Reverse(bs);
            int fdToRead = BitConverter.ToInt32(bs,0);
            Debug.WriteLine(fdToRead);
        }
        using (DataWriter writer = new DataWriter(clientTcpSocket.OutputStream))
        {
            writer.WriteString(String.Format("Client Start"));
            await writer.StoreAsync();
        }
        timer.Start();
        ListenTcpClient(clientTcpSocket);
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
}

 private async Task DoSomethingElse()
 {
        // do something
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM