如何在F#Xamarin.Forms应用程序中使用C#任务?
我想学习一些F#,所以我决定用它创建一个Xamarin.Forms应用程序,但我对F#中的异步和函数编程非常不熟悉。我正在使用Xam.Plugins.Media C#library尝试拍照,但如何在F#Xamarin.Forms应用程序中使用C#任务?,xamarin.forms,f#,c#-to-f#,Xamarin.forms,F#,C# To F#,我想学习一些F#,所以我决定用它创建一个Xamarin.Forms应用程序,但我对F#中的异步和函数编程非常不熟悉。我正在使用Xam.Plugins.Media C#library尝试拍照,但CrossMedia.Current.TakePhotoAsync()的行为与我在C#中使用的行为不同 以下是我在F#中的内容: type主页()= 继承ContentPage() 让u=base.LoadFromXaml(typeof) 让viewModel=base.BindingContext:?>M
CrossMedia.Current.TakePhotoAsync()
的行为与我在C#中使用的行为不同
以下是我在F#中的内容:
type主页()=
继承ContentPage()
让u=base.LoadFromXaml(typeof)
让viewModel=base.BindingContext:?>MainViewModel
让checkNull(x:'T)=
将x与
|null->raise(NullReferenceException(String.Format(“{0}为null”,x)))
|_ux->x
此成员。拍照(发件人:obj,e:EventArgs)=
如果没有CrossMedia.Current.IsCameraAvailable | |没有CrossMedia.Current.IsTakePhotoSupported,则
升起(异常(“不支持摄像头”))
其他的
让媒体选项=
Plugin.Media.Abstractions.StoreCameramedOptions(
Directory=“Test”,
SaveToAlbum=true,
压缩质量=75,
自定义photosize=50,
PhotoSize=PhotoSize.MaxWidthHeight,
MaxWidthHeight=Nullable(2000),
DefaultCamera=CameraDevice.Front)
让file=CrossMedia.Current.TakePhotoAsync(mediapoptions)|>Async.waittask |>Async.RunSynchronously
viewModel.Stream我怀疑这里的问题是您正在使用RunSynchronously
来拍摄一张照片,而这张照片可能没有达到您期望的效果。您可以将同步运行
想象为对.Net任务对象调用.Result
。作为猜测,这将导致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
member this.TakePhoto(发件人:obj,e:EventArgs)=
异步的{
如果CrossMedia.Current.IsCameraAvailable不可用,则返回()
其他的
let!file=CrossMedia.Current.TakePhotoAsync(Plugin.Media.Abstractions.StoreCameramedOptions(
Directory=“Test”,
SaveToAlbum=true,
压缩质量=75,
自定义photosize=50,
PhotoSize=PhotoSize.MaxWidthHeight,
MaxWidthHeight=2000,
DefaultCamera=CameraDevice.Front))|>Async.Task
如果文件为空,则返回()
其他的
viewModel.Stream Async.Startask
如果您愿意依赖外部库,异步块也可以用任务计算表达式替换如果您不以任何方式将此问题与Xamarin和C#联系起来,您可能会得到答案。任务不是C#特定的-它们也在F#中使用。您的问题似乎不是很Xamar具体来说,它的行为就像我之前尝试的async{}
设置,或者我尝试使用FSharp.Control.Tasks.V2.task{}
,它在单击按钮时不做任何操作。我甚至能够获得权限对话框提示的唯一方法是使用Async.RunSynchronously
,这会卡在同一点上,就像我将C版本切换为使用Wait
和Result
,所以我采用Async{}
在F#中,不是100%等同于C#wait
你能更新你的问题来显示你的TakePhoto
方法是如何被调用的吗?看起来你的C#方法是一个按钮点击事件处理程序,但是你的F#方法不是从我能看到的任何地方被调用的按钮点击事件是在Xaml的F#侧被设置的
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