简体   繁体   中英

c# make UI calls when TCPClient receives data async

I have a Forms app and a Console server app connected with TCPClient. The Forms app opens up a dialog for user authentication, when user clicks the Login button, a request is sent to the server. The server then responds if the login credentials were valid or not. The Forms app receives the response asynchronously and gives out an error message or closes the authentication window and continues.

After reading this post about SynchronizationContext I have created a working solution which calls functions on the UI thread from the thread that handles the server response. My question is, is there a better way to do this in C#?

I read quite a bit on async/await but haven't found a way to await for a particular server response. The Client handles the responses using stream.BeginRead() from a buffer.

Capturing UI Context:

public static SynchronizationContext uiContext;

public MainForm(string[] args)
{
    InitializeComponent();
}

private void MainForm_Load(object sender, EventArgs e)
{
    uiContext = SynchronizationContext.Current;
    //etc
}

Calling functions on the LoginForm when Client receives particular server response for authentication through stream.BeginRead() :

private void UserAuthenticationAnswerReceived(byte[] _data)
{
    SynchronizationContext uiContext = MainForm.uiContext;
    //if auth was unsuccessful, the data will be only 1 int in length
    if (_data.Length <= sizeof(int))
    {
        Debug.WriteLine("Authentication failed.");
        uiContext.Post(UserLogin.userLoginFrm.AuthUnsuccessfulAsync, null);
    }
    else
    {
        Debug.WriteLine("Authentication successful.");
        uiContext.Post(UserLogin.userLoginFrm.AuthSuccessfulAsync, user);
    }
}

I am quite new to networking and may be missing a more fundamental concept about client/server model and how to manage responses asynchronously.

My question is, is there a better way to do this in C#?

Generally, it's easier to use Task-based APIs such as ReadAsync instead of old-style IAsyncResult -based APIs such as BeginRead .

But for the general solution of notifying the UI from a background thread, the best solution is to capture the SynchronizationContext .

However, if you have a command/response protocol, with the client only receiving responses for commands it has sent, then you can get a much simpler solution using async / await .

I am quite new to networking and may be missing a more fundamental concept about client/server model and how to manage responses asynchronously.

The first thing I'd recommend is to self-host an ASP.NET Core WebApi. Then you can use an off-the-shelf HttpClient to handle the commands and responses. Custom network protocols are extremely complex to get right, and they're even more complex if you're not familiar with asynchronous code.

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