Currently I have a piece of code written in C# that is being consumed by a piece of F# code both being .NET libraries. Here is the issue:
Assume I have the following class in the C# library:
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);
}
}
}
And is then overridden in F# as such:
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>' *)
The issue is the this.OnSetup()
member is trying to return Async<unit>
but the C# library is expecting a normal empty Task
. I've tried looking through the MSDN Control.Async
documentation but did not find much of any avail. Async.StartAsTask
still returns a typed task, i.e. Task<'a>
. So something like this does not seem to solve the problem:
override this.OnSetup(): Task =
let f: Async<unit> = async {
// Implementation specific setup code here
}
Async.StartAsTask f
Instead now you will be greeted by a similar error message:
This expression was expected to have type
Task
but here has type
Task<'a>'
You may then ask why I am not using events in the first place. The main reason for that is then since you are going to be returning async void
there is no way to properly use await
on the event to complete.
Finally, I luckily have control over both the C# and F# libraries. Any reasonable way to override this protected virtual async Task
function or alike would be greatly appreciated.
In asynchronous virtual learning the learner enriches their knowledge at their own tempo at a time convenient for themselves. Learning is not restricted by place and time. The learning process is not dependent on fixed time intervals which serve to regulate the sequence of activities.
An async method runs synchronously until it reaches its first await expression, at which point the method is suspended until the awaited task is complete. In the meantime, control returns to the caller of the method, as the example in the next section shows.
Interfaces can't use async in a method declaration, simply because there is no need. If an interface requires that a method returns Task , the implementation may choose to use async , but whether it does or not is a choice for the implementing method.
Given that Task<'a>
derives from Task
you can just slightly modify your last snippet
override this.OnSetup(): Task =
let f: Async<unit> = async {
// Implementation specific setup code here
}
upcast Async.StartAsTask f
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With