Dot-Net
F# - 將 Task<unit> 轉換為普通任務
我正在使用 Giraffe 創建具有非同步工作流的本機 .NET 任務,因為我需要與 Discord.NET 庫的互操作性。我有一個需要 a
Task的事件,但是我正在編寫的事件處理程序返回 aTask<unit>並且由於某種原因,類型檢查器不夠聰明,無法意識到它是同一件事。有沒有辦法將其轉換Task<unit>為直線上升Task?這是我的程式碼:
let messageReceived (msg : SocketMessage) = task { let author = msg.Author.Username let text = msg.Content match msg.Author.Username with | "Monika" -> () | usr -> if text.ToLower().StartsWith "<@407367655830585344> say" then text.Substring 26 |> msg.Channel.SendMessageAsync |> ignore else if text.ToLower().StartsWith "<@407367655830585344>" then let response = (Lines.VoiceLines |> Extras.randomElement).Replace("[player]", author) msg.Channel.SendMessageAsync response |> ignore else if text.ToLower().StartsWith "delete" then text.Substring 7 + ".chr deleted" |> msg.Channel.SendMessageAsync |> ignore else if Extras.onein 10 then let response = (Lines.VoiceLines |> Extras.randomElement).Replace("[player]", author) msg.Channel.SendMessageAsync response |> ignore } _client.add_MessageReceived (fun m -> messageReceived m)最後一行生成一個錯誤,說明該
MessageReceived事件需要一個帶有簽名的函式SocketMessage -> Task:錯誤 FS0001:此表達式的類型應為“任務”,但此處的類型為“任務<單元>”
Task是 的基類Task<T>,因此您應該能夠向上Task<unit>轉換為Taskwith:>運算符。嘗試這樣的事情:(fun m -> messageReceived m :> Task)我認為這個最小的例子重現了這個問題:
// int -> Task<unit> let sleepTaskT (m : int) = Async.Sleep m |> Async.StartAsTask // (int -> Task) -> Task let foo (f : int -> Task) = f 1000 // "This expression was expected to have type 'Task' but here has type 'Task<unit>'" foo (fun m -> sleepTaskT m) // this works by explicitly upcasting sleepTaskT's Task<unit> to Task foo (fun m -> sleepTaskT m :> Task)