簡體   English   中英

使用在C#中聲明的虛擬異步任務並在F#中覆蓋它

[英]Use a virtual async Task declared in C# and override it in F#

目前我有一段用C#編寫的代碼,它被一段F#代碼用作.NET庫。 這是問題:

假設我在C#庫中有以下類:

namespace Jaxrtech.Logic
{
    public class Initializer
    {
        public Initializer()
        {
        }

        public async Task Setup()
        {
            // Run implementation independed setup here

            // Now call the implementation specific override
            await OnSetup();

            // Do any additional setup after the implemntation specific stuff
        }

        // Allow for custom setup tasks to be ran by the Initializer
        protected virtual async Task OnSetup()
        {
            // Return a completed task by default
            await Task.FromResult(0);
        }
    }
}

然后在F#中覆蓋,如下:

open System.Threading.Tasks
open Jaxrtech.Logic

type CustomInitializer() =
    inherit Initializer()

    ...

    override this.OnSetup(): Task = async {
        // custom async logic here
        // ex:
        do! updateTables()
        do! validateData()
    }

    (* Error: This expression was expected to have type
                Task
              but here has type
                Async<'a>' *)

問題是this.OnSetup()成員正在嘗試返回Async<unit>但C#庫期望一個正常的空Task 我試過通過MSDN Control.Async文檔,但沒有找到任何有用的。 Async.StartAsTask仍然返回一個類型化的任務,即Task<'a> 所以這樣的事情似乎無法解決問題:

override this.OnSetup(): Task =
    let f: Async<unit> = async {
        // Implementation specific setup code here
    }
    Async.StartAsTask f

相反,現在您會收到類似的錯誤消息:

This expression was expected to have type  
  Task  
but here has type  
  Task<'a>'

然后你可以問我為什么不首先使用事件。 這樣做的主要原因是因為你要返回async void所以無法在事件上正確使用await來完成。

最后,幸運的是我可以控制C#和F#庫。 任何合理的方式來覆蓋這個protected virtual async Task函數或類似的將非常感激。

鑒於Task<'a>派生自Task您可以稍微修改您的最后一個片段

override this.OnSetup(): Task =
    let f: Async<unit> = async {
    // Implementation specific setup code here
    }
    upcast Async.StartAsTask f

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM