I have a pretty basic script in my Unity game which is trying to submit form data in POST to a server. But unity seems to freeze/hang indefinitely. I am confused why this is happening and so i don't know how to solve the problem.
I made my code loosely following this article: https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/console-webapiclient#making-web-requests
My server does receive the request and does write one back. But because unity is frozen its not really usable at the moment.
My class looks like this:
public class HTTPManager : MonoBehaviour
{
private static HttpClient client = new HttpClient();
private void Awake()
{
client.BaseAddress = new Uri("http://localhost:8080/");
ProcessRepositories().Wait();
}
private async Task ProcessRepositories()
{
client.DefaultRequestHeaders.Accept.Clear();
FormUrlEncodedContent content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("u", "test")
});
//this goes to http://localhost:8080/hello with POST u=test
HttpResponseMessage result = await client.PostAsync("hello",content);
Debug.Log("Is Success: "+result.IsSuccessStatusCode);
Debug.Log("Status code: "+result.StatusCode);
Debug.Log("Reason Phrase: "+result.ReasonPhrase);
Debug.Log("Headers: "+result.Headers);
Debug.Log("Content: "+result.Content);
Debug.Log("Request Message: "+result.RequestMessage);
Debug.Log("Version: "+result.Version);
}
}
Whats causing the hanging issue??
ProcessRepositories().Wait();
is blocking on async
code and it is causing a deadlock. Stephen Clearly has a whole series of posts on this.
Either make all the code async
all the way up or schedule continuations on your Task
.
EDIT: It seems that Awake
is a Unity
method. For this you have 4 options:
1) Remove async Task
from ProcessRepositories()
. Remove the await
in the method body and make your calls to your server synchronous. This will cause jitters and it not a recommended solution in a game environment.
2) Remove .Wait()
from ProcessRepositories()
. This will cause your code to async post to server but you won't be able to do anything with the the response. This is fine if you don't care about the response.
3.) If you do care about the response, you can schedule Continuations
on ProcessRepositories()
. This is a type of "callback" that will run when your Task
has RanToCompletion
or it errored out. To achieve this, change ProcessRepositories()
to ProcessRepositories().ContinueWith(task=>
{
// in here you can access task.Result to get your response
})
and change your ProcessRepositories
method to return the HttpResponseMessage
result
i.e return await client.PostAsync("hello",content);
4) Use ConfigureAwait(false)
as mentioned below but that will return the result on a different context and seeing that this Unity, you probably want the result on the UI thread, so just watch out for that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With