Every async method has its context.
When the Task starts it might run in a new SynchronizationContext. "Might" because if the task is already completed, like Task.FromResult(0), then no other SynchronizationContext is created and the original one is used.
Awaiting for a task means that when the task is finished, the next statement will run in the original SynchronizationContext.
This behavior can be changed using the Task.ConfigureAwait(continueOnCapturedContext: false). This means that the next statement will continue on the same context. But this will change nothing by doing Task.FromResult(0).ConfigureAwait(false) because the task is already completed and the original context will be used.
Therefore your Remote.Login("user","password"); will be run in the original context, thus blocking the UI thread which runs on the same context.
If you would have something like:
public async void LoginButtonClicked()
{
await Task.Delay(5000).ConfigureAwait(false);
Remote.Login("user","password");
}
Then Remote.Login("user","password"); would execute in the thread pool context thus being on a different context than the original UI context.
So the best way to fix your code is to create a Remote.LoginAsync() as stated in @Nicholas W answer.
NOTE on performance: if you have an async method with multiple await statements, and you don't need some of those awaits to do work on UI or web app thread, then you can use Task.ConfigureAwait(false) in order to prevent multiple switches to the UI/web-app context which slices its execution time.
awaitonly does anything fancy if the thing to it's right has not completed. aTask.FromResultalways returns a completed task, and so the method continues merrily on its way past thatawaitpoint.Task.FromResultshould not be called withawait: Should I await on Task.FromResult Method Calls?