Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在F#Xamarin.Forms应用程序中使用C#任务?_Xamarin.forms_F#_C# To F# - Fatal编程技术网

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

如何在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

我想学习一些F#,所以我决定用它创建一个Xamarin.Forms应用程序,但我对F#中的异步和函数编程非常不熟悉。我正在使用Xam.Plugins.Media C#library尝试拍照,但
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