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);
}
}
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);
});
}
}