Я хотел изучить 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 # в полностью функциональном аспект, но что мне не хватает, чтобы заставить его работать или есть какое-то ограничение, о котором я не знаю, когда использую задачу C# в F #?
Я пытался использовать выражение async {}
, которое ничего не делало на кнопке щелкните, но я предполагаю, что это помещает TakePhotoAsync
в фоновый поток, когда он, вероятно, должен быть запущен в основном потоке. То, что мне сейчас показалось, работает на полпути: показывать диалоговое окно с разрешениями и, в конечном итоге, показывать черный экран, как будто камера запускается, но он застревает там и фактически не показывает подачу камеры.