Are there any caveats when using HttpClient with IL2CPP?

About 50% of the time, the library I am working on freezes on a certain network call that is making use of HttpClient.SendAsync(). I am working on getting a smaller test case to submit, but this problem only happens on Unity iOS (Mono2x has different problems with EXC_BAD_ACCESS at the moment so cannot confirm if it works there or not, but on Standalone this works fine). When I pause to get the thread stack traces I notice a similar pattern each time:

  1. There are two threads labeled Async I/O Thread that are both blocking on socket receive functionality.
  2. I have one thread of my own blocking on receiving data from a hanging HTTP connection (this is on purpose)
  3. No other threads go through any of my code, which suggests that the problem is between SendAsync and ContinueWith

Before I get an actual reproduction case ready, is there anything anyone can think of that could be causing this? Does IL2CPP hard limit to two HTTP connections the way that Mono does by default? Can this be altered?

Thanks!

@j-borden

I’m not aware of what might be causing this, and I don’t think that it is something we’ve seen yet with IL2CPP. The behavior of IL2CPP should be the same as it is with Mono in this case, and IL2CPP does not expose any way to modify it.

I have probably similar issue with IL2CPP and Unity 2019.1.0f2. Some await HttpClient.SendAsync() works and some get stuck. Probably the problem is when await HttpClient.SendAsync() is called from non-main thread, i.e. without Unity SynchronizationContext. The process (window) cannot be closed, probably waiting for SendAsync() to finish.
I’ll try to isolate the issue to some example project.

1 Like

Please submit a bug report if you can isolate this, thanks!

So the bug is the FileStream(useAsync:true), not the HttpClient. I have filled the bug https://fogbugz.unity3d.com/default.asp?1156384_t1ec5ls4mtugdoag

1 Like

Another problem is, that the HttpClient ignores Windows proxy settings. I have found a workaround for the Mono build:

var handler = new HttpClientHandler();
handler.UseDefaultCredentials = true;
handler.Proxy = System.Net.WebRequest.DefaultWebProxy;
var client = new HttpClient(handler);

But it does not work for IL2CPP! I have filled a bug https://fogbugz.unity3d.com/default.asp?1156595_buha3p1v4iq7vpv9

Another difference is in the ServicePointManager.DefaultConnectionLimit = 2 for the Mono build, but 10 for the IL2CPP build. DefaultConnectionLimit == 10 should be for server ASP.NET, not a desktop app, see ServicePointManager.DefaultConnectionLimit Vlastnost (System.Net) | Microsoft Learn Anyway, Unity should have same settings regardless of chosen build.

I have filled a bug https://fogbugz.unity3d.com/default.asp?1156607_n5mttn2knh0s3fh1

Thanks for the bugs, we will investigate them.

Hey, this still happen in 2021.3.10, have you found any solutions for IL2CPP build?
acording to the fogbugz, they are not going to fixed this.

I’m using 2020.3.30 and encountered an issue about HttpClient. The process may become freezing for a while when it calls Task.Delay in main thread and receive response from HttpClient in a background thread.

Actually, I found the root cause: the timers created in the background thread leaks and it has been fixed in 2021.2 and above. Hope the fix can be backported to 2020.

I submitted a bug report for it: IN-16679

UPDATE:
They decided to not backport the fix to 2020: Unity Issue Tracker - Unity Player freezes when using an HTTP server to download a bundle

1 Like

@JoshPeterson - this issue is still evident in unity 2023.1.16f1:-

try
{
    HttpClientHandler handler = new HttpClientHandler();

    HttpClient client = new HttpClient(handler);
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://127.0.0.1:9976/services/test");

    request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("user:pass")));
    request.Content = new StringContent("user=user345");
    request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");

    HttpResponseMessage response = await client.SendAsync(request); //Freeze happens here
    response.EnsureSuccessStatusCode();

    return await response.Content.ReadAsStringAsync();
}
catch
{
    return null;
}

Any workarounds for this? Symptoms are that when the SendAsync function executes, it hangs the unity editor with the progress dialog stuck. VS will exit fine and return to development mode.

@xmedeko - incorrect assumption, this is related to the HttpClient.