Reputation: 8280
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??
Upvotes: 4
Views: 2176
Reputation: 127543
Don't use HttpClient with unity, use the class WWW and unity's built in coroutine features, yield return it and it will wait for the download to complete.
public class HTTPManager : MonoBehaviour
{
private IEnumerator Awake()
{
return ProcessRepositories();
}
private IEnumerator ProcessRepositories()
{
var form = new WWWForm();
form.AddField("u", "test");
var www = new WWW("http://localhost:8080/hello", form);
yield return www;
Debug.Log("responseHeaders: "+www.responseHeaders);
Debug.Log("text: "+www.text);
}
}
Upvotes: -2
Reputation: 5472
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.
Upvotes: 4