Search code examples
c#multithreadingmaui

MAUI: Android vs IOS Threading restrictions


I've got an async function that gets streaming responses from OpenAI and populates a View with the results. Due to this, the function accesses both the network and the UI.

If I call the function as await PromptAISubThread(text, token); then Android gets upset as it by default does not allow network connections from the main thread. I end up with a android.os.NetworkOnMainThreadException`.

The solution is to call the function via a Task.Run, to run it on a separate thread. But then IOS gets upset as it doesn't allow UI to be accessed from a thread other than the UI (main) thread and throws a UIKit.UIKitThreadAccessException.

The code snippet below naturally solves the problem, but I am trying to avoid conditional compilation as much as possible. Is there a better way of handling this situation?

#if IOS
        await PromptAISubThread(text, token);
#else
        await Task.Run(async () => await PromptAISubThread(text, token));
#endif
private async Task<bool> PromptAISubThread(string text, CancellationToken token)
{
    AsyncCollectionResult<StreamingChatCompletionUpdate> chatStream;
    await foreach (var completionUpdate in chatStream)
        {
            UpdateUI(completionUpdate);
        }
}

Solution

  • use MainThread

    private async Task<bool> PromptAISubThread(string text, CancellationToken token)
    {
        AsyncCollectionResult<StreamingChatCompletionUpdate> chatStream;
        await foreach (var completionUpdate in chatStream)
            {
    
              MainThread.BeginInvokeOnMainThread(() =>
              {
                // Code to run on the main thread
                UpdateUI(completionUpdate);
              });
            }
    }