如何使用 F# Avalonia FuncUI 选择文件,异步问题

问题描述 投票:0回答:1

我有一个可用的 FuncUI 应用程序,但添加文件选择器以从文件系统获取一些文本很棘手。我已根据 Avalonia FuncUI 主页上计数器应用程序的修改版本将我的应用程序精简为以下应用程序。它运行良好,但在按下“加载文件”按钮后挂在 Async.RunSynchronously 的第 34 行:

namespace CounterApp

open Avalonia
open Avalonia.Controls.ApplicationLifetimes
open Avalonia.Themes.Fluent
open Avalonia.FuncUI.Hosts
open Avalonia.Controls
open Avalonia.FuncUI
open Avalonia.FuncUI.DSL
open Avalonia.Layout
open Avalonia.Platform.Storage
open System.IO


module Main =

    let view () =
        Component(fun ctx ->
            let state = ctx.useState 0

            let top = TopLevel.GetTopLevel ctx.control

            let useFiles() =
              async {
                let options = FilePickerOpenOptions(Title = "Open Text File", AllowMultiple = false)
         
                let! result = top.StorageProvider.OpenFilePickerAsync(options) |> Async.AwaitTask
          
                return result
              }
            
            let callback _ =
              useFiles()
              |> Async.RunSynchronously |> ignore

            DockPanel.create [
                DockPanel.children [
                    Button.create [
                        Button.dock Dock.Bottom
                        Button.onClick callback
                        Button.content "Load file"
                        Button.horizontalAlignment HorizontalAlignment.Stretch
                        Button.horizontalContentAlignment HorizontalAlignment.Center
                    ]                   
                ]
            ]
        )

type MainWindow() =
    inherit HostWindow()
    do
        base.Title <- "Counter Example"
        base.Content <- Main.view ()

type App() =
    inherit Application()

    override this.Initialize() =
        this.Styles.Add (FluentTheme())
        this.RequestedThemeVariant <- Styling.ThemeVariant.Dark

    override this.OnFrameworkInitializationCompleted() =
        match this.ApplicationLifetime with
        | :? IClassicDesktopStyleApplicationLifetime as desktopLifetime ->
            desktopLifetime.MainWindow <- MainWindow()
        | _ -> ()

module Program =

    [<EntryPoint>]
    let main(args: string[]) =
        AppBuilder
            .Configure<App>()
            .UsePlatformDetect()
            .UseSkia()
            .StartWithClassicDesktopLifetime(args)

这是我对可能可行的方法的最佳近似,但我现在陷入困境。关于如何使这个工作代码有任何想法?

asynchronous f# avalonia
1个回答
0
投票

在查看是否有人回答了我的问题时,Google 向我报告了 github 上的 Avalonia FuncUI 链接,这反过来又让我阅读了一篇关于 Elmish 的文章,这是我的应用程序的更广泛上下文。

结果我需要做的就是将回调设为 void 函数,并立即开始任务:

let useFiles() =
  async {
    let options = FilePickerOpenOptions(Title = "Open Text File",
                                        AllowMultiple = false)
         
    let! result = 
      top.StorageProvider.OpenFilePickerAsync(options)
      |> Async.AwaitTask
                
    System.Console.WriteLine "result now available"
  }
            
let callback _ =
  useFiles()
  |> Async.StartImmediate

这成功调用了文件选择器,从而解决了我所说的问题。我现在可以继续并使用

result
中返回的文件选择器的选择。

© www.soinside.com 2019 - 2024. All rights reserved.