【发布时间】:2020-05-01 02:40:39
【问题描述】:
我想学习一些 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 放在后台线程上,而它可能必须在主线程上运行。我现在似乎通过显示权限对话框并最终显示一个黑屏就像相机正在启动一样工作,但它卡在那里并且从未真正显示相机供稿。
【问题讨论】:
-
如果您不以任何方式将此问题与 Xamarin 和 C# 相关联,也许您会得到答案。任务不是特定于 C# 的 - 它们也在 F# 中使用。您的问题似乎不是 Xamarin 特有的。
标签: xamarin.forms f# c#-to-f#