gpt4 book ai didi

c# - 是否可以等待 Device.BeginInvokeOnMainThread 代码完成(使用 UI 调用的结果继续后台工作)

转载 作者:太空宇宙 更新时间:2023-11-03 19:40:12 25 4
gpt4 key购买 nike

在我的代码中,我有一个名为“ShowMessageBoxAsync”的任务。我想使用此代码向用户显示(并等待)DisplayAlert 并返回结果。像这样: var messageBoxResult = await View.ShowMessageBoxAsync("这是一个错误");

ShowMessageBoxAsync 的代码是:

public async System.Threading.Tasks.Task<bool> ShowMessageBoxAsync(string message)
{
var result = false;
Device.BeginInvokeOnMainThread(async () =>
{
result = await DisplayAlert("Error", message, "OK", "Cancel");
});
return result;
}

在我添加 Device.BeginInvokeOnMainThread 之前,任务给了我一个异常,它没有在主/UI 线程上运行。所以在添加了BeginInvokeOnMainThread之后,就开始正常工作了,没有异常。然而,问题是代码直接转到结果,而不等待“await DisplayAlert”的结果。

是否只有在 Device.BeginInvokeOnMainThread 代码完成后才返回“result”的值?

我对此做了一些研究,有人建议使用 TaskCompletionSource,但这会阻塞 UI 线程并且 DisplayAlert 根本不会显示。

最佳答案

I did some research about it and someone suggested to use a TaskCompletionSource

这是正确的解决方案。 TaskCompletionSource 充当 Task 的“完成者”。在这种情况下,此 Task 代表用户交互,因此您希望 UI 线程上的代码完成 Task,而后台线程上的代码(a)等待“任务”。

所以,像这样:

public Task<bool> ShowMessageBoxAsync(string message)
{
var tcs = new TaskCompletionSource<bool>();
Device.BeginInvokeOnMainThread(async () =>
{
try
{
var result = await DisplayAlert("Error", message, "OK", "Cancel");
tcs.TrySetResult(result);
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
});
return tcs.Task;
}

这应该可以让您暂时畅通无阻。但是,更好的长期解决方案是让您的后台线程逻辑采用某种“与 UI 交互”的界面,如下所示:

public interface IAskUser
{
Task<bool> AskUserAsync(string message);
}

使用与上述类似的特定于 Xamarin Forms 的实现。

这样一来,您的后台线程逻辑就不会绑定(bind)到特定的 UI,并且可以更轻松地进行单元测试和重用。

关于c# - 是否可以等待 Device.BeginInvokeOnMainThread 代码完成(使用 UI 调用的结果继续后台工作),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54573940/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com