gpt4 book ai didi

xamarin.forms - 如何在 F# Xamarin.Forms 应用程序中使用 C# 任务?

转载 作者:行者123 更新时间:2023-12-03 20:54:04 26 4
gpt4 key购买 nike

我想学习一些 F#,所以我决定用它创建一个 Xamarin.Forms 应用程序,但我对 F# 中的异步和函数式编程非常不熟悉。我正在使用 Xam.Plugins.Media C# 库尝试拍照,但 CrossMedia.Current.TakePhotoAsync()与我在 C# 中使用它的行为不同。

这是我在 F# 中的内容:

    type MainPage() =
inherit ContentPage()
let _ = base.LoadFromXaml(typeof<MainPage>)

let viewModel = base.BindingContext :?> MainViewModel
let checkNull (x : 'T) =
match x with
| null -> raise (NullReferenceException(String.Format("{0} is null", x)))
| _ -> x

member this.TakePhoto(sender : obj, e : EventArgs) =
if not CrossMedia.Current.IsCameraAvailable || not CrossMedia.Current.IsTakePhotoSupported then
raise (Exception("Camera not supported"))
else
let mediaOptions =
Plugin.Media.Abstractions.StoreCameraMediaOptions(
Directory = "Test",
SaveToAlbum = true,
CompressionQuality = 75,
CustomPhotoSize = 50,
PhotoSize = PhotoSize.MaxWidthHeight,
MaxWidthHeight = Nullable(2000),
DefaultCamera = CameraDevice.Front)
let file = CrossMedia.Current.TakePhotoAsync(mediaOptions) |> Async.AwaitTask |> Async.RunSynchronously
viewModel.Stream <- (checkNull file).GetStream()

这是 C# 的等价物:
takePhoto.Clicked += async (sender, args) =>
{
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
return;

var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
Directory = "Test",
SaveToAlbum = true,
CompressionQuality = 75,
CustomPhotoSize = 50,
PhotoSize = PhotoSize.MaxWidthHeight,
MaxWidthHeight = 2000,
DefaultCamera = CameraDevice.Front
});

if (file == null)
return;

viewModel.Stream = file.GetStream();
};

我知道我没有在功能齐全的方面使用 F#,但是我缺少什么才能让它工作,或者在 F# 中使用 C# 任务时是否有一些我不知道的限制?

我尝试使用 async {}表达式,它在按钮点击时什么也没做,但我认为这是放置 TakePhotoAsync当它可能必须在主线程上运行时,放到后台线程上。我现在似乎通​​过显示许可对话框并最终显示像相机启动一样的黑屏来工作,但它卡在那里并且从未真正显示相机提要。

最佳答案

我怀疑这里的问题是您正在使用 RunSynchronously拍摄一张可能没有达到您期望的照片。你可以想到RunSynchronously就像打电话.Result在 .Net 任务对象上。因此,作为猜测,这会导致 Xamarin 标准库中某处出现死锁。

相反,如果您希望您的 F# 代码更接近您的 C# 代码,那么您将需要如下内容:

member this.TakePhoto(sender: obj, e : EventArgs) =
async {
if not CrossMedia.Current.IsCameraAvailable ... then return ()
else
let! file = CrossMedia.Current.TakePhotoAsync(Plugin.Media.Abstractions.StoreCameraMediaOptions(
Directory = "Test",
SaveToAlbum = true,
CompressionQuality = 75,
CustomPhotoSize = 50,
PhotoSize = PhotoSize.MaxWidthHeight,
MaxWidthHeight = 2000,
DefaultCamera = CameraDevice.Front)) |> Async.AwaitTask

if isNull file then return ()
else
viewModel.Stream <- file.GetStream()
} |> Async.StartAsTask

如果您愿意依赖外部库,也可以将 async 块替换为任务计算表达式

关于xamarin.forms - 如何在 F# Xamarin.Forms 应用程序中使用 C# 任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61536010/

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