【发布时间】:2019-12-18 09:12:28
【问题描述】:
以下内容在某种程度上动摇了我基于 async/await 的信念系统。在 Xamarin/iOS 下,以下失败,表示 UI 相关的事情正在非 UI 线程中完成。添加检查点表明上下文确实在异步文件写入之后切换。
我的理解是缺少一个ConfigureAwait,下面的应该是完全安全的。我假设这是我不知道的 Xamarin 细微差别,但很难理解这可能是什么。
同样的代码在 Android 和 UWP 上运行良好。
private async void ShareButton_OnClicked(object sender, EventArgs e)
{
if (!(BindingContext is PhotoViewModel photoViewModel))
{
return;
}
// in UI context
var name = photoViewModel.Name ?? "temp.jpg";
var file = Path.Combine(FileSystem.CacheDirectory, name);
using (var stream = new FileStream(file, FileMode.Create, FileAccess.Write))
{
await stream.WriteAsync(photoViewModel.Data, 0, photoViewModel.Data.Length);
}
// not in UI context!
// calling this causes SIGABRT: UIKit Consistency error
await Share.RequestAsync(new ShareFileRequest(new ShareFile(file)));
}
【问题讨论】:
-
在
await之前检查SynchronizationContext.Current的值。 Xamarin 应该在启动事件处理程序之前进行设置,以便await在 UI 上下文中恢复。 -
@StephenCleary 当你说检查值时,我不确定我在寻找什么。我确实尝试调用 MainThread.IsMainThread(一个 Xamarin Essentials 的东西,似乎在 iOS 上包装了 NSThread),这在之前是真的,之后是假的。在这两种情况下,当前上下文都不为空,但我不知道除此之外还要寻找什么。谢谢。
-
查看是不是
null,如果不是,是什么类型。 -
在它之前和之后都不为空并且类型为 UIKit.UIKitSynchronizationContext
-
那么您应该跟进 Xamarin 团队。
标签: ios xamarin async-await