F # async / wait in viewmodel

My ViewModel in F #

I am trying to use F # instead of C # to implement my ViewModel. I follow this article (by the way, is there something newer or any better suggestion?).

So, let's say that I have a basic implementation of the presentation model ( MVVM.ViewModel, it is in C #, but I can refer to it from F #) and a simple property Status.

namespace FuncViewModel
open MVVM.ViewModel
open System

    type MyFuncViewModel() = 
        inherit ViewModelBase()

        let mutable status=""

        member this.RunSetStatus() =
            status <- "Reset @" + DateTime.Now.ToString "yy.MM.dd hh:mm:ss"
            base.OnPropertyChanged("Status")

        member this.SetStatus = new DelegateCommand(fun _ -> this.RunSetStatus() )


    member this.Status 
        with get() =
            status
        and set(value) =
             status <- value
             base.OnPropertyChanged(fun () -> this.Status)

Everything works as expected, so good (but let me know if you notice any conceptual error or if you find a more idiomatic version for the above code)

Async / await template view

This is where I am wrong: I know how to do this in C #, but I'm not sure about that in F #.

I tried with the following.

member this.RunSetStatus() =
    status <- "Start resetting @" + DateTime.Now.ToString "yy.MM.dd hh:mm:ss"
    base.OnPropertyChanged("Status")
    let task = async {

        do! Async.Sleep (30 * 1000) 

    }
    Async.StartImmediate(task)
    status <- "Reset done @" + DateTime.Now.ToString "yy.MM.dd hh:mm:ss"
    base.OnPropertyChanged("Status")

, - WPF - : .

Async.StartImmediate(task) Async.RunSynchronously(task), , , , , , .

member this.RunSetStatus() =
    status <- "Start resetting @" + DateTime.Now.ToString "yy.MM.dd hh:mm:ss"
    base.OnPropertyChanged("Status")
    let task = async {

        do! Async.Sleep (30 * 1000) 

        status <- "Reset done @" + DateTime.Now.ToString "yy.MM.dd hh:mm:ss"
        base.OnPropertyChanged("Status")

    }
    Async.StartImmediate(task)

'OnPropertyChanged' . . -.

()

,

member this.RunSetStatus() =
    status <- "Start resetting @" + DateTime.Now.ToString "yy.MM.dd hh:mm:ss"
    base.OnPropertyChanged("Status")
    let task = async {

        do! Async.Sleep (30 * 1000) 

    }
    Async.StartWithContinuations(task, 
        (fun _ -> this.Status <- "Reset done @" + DateTime.Now.ToString "yy.MM.dd hh:mm:ss"),
        (fun _ -> this.Status <- "Operation failed."),
        (fun _ -> this.Status <- "Operation canceled."))

ArgumentException

: MyFuncWPF.exe Framework : v4.0.30319 : - . Info: System.ArgumentException Stack: at MVVM.ViewModel.ViewModelBase.OnPropertyChanged [System.__ Canon, mscorlib, = 4.0.0.0, = , PublicKeyToken = b77a5c561934e089] FuncViewModel.MyFuncViewModel.set_Status (System.String) . $MyVMLib + RunSetStatus @20.Invoke(Microsoft.FSharp.Core.Unit) Microsoft.FSharp.Control.CancellationTokenOps+StartWithContinuations@1274 [[System.__ Canon, mscorlib, = 4.0.0.0, = , PublicKeyToken = b77a5c561934e089]]. (System.__ Canon) . $Control.loop @430-52 (Microsoft.FSharp.Control.Trampoline, Microsoft.FSharp.Core.FSharpFunc 2<Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Control.FakeUnitValue>) at Microsoft.FSharp.Control.Trampoline.ExecuteAction(Microsoft.FSharp.Core.FSharpFunc 2) at. $Control + -ctor @507.Invoke(System.Object) System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object

2 -

- - OnPropertyChanged ( # )

    member this.Status 
        with get() =
            status
        and set(value) =
             status <- value
             base.OnPropertyChanged("Status")
+4
1

, F # โ€‹โ€‹ MemberExpression:

    protected virtual void OnPropertyChanged<T>(Expression<Func<T>> selectorExpression)
    {
        if (selectorExpression == null)
            throw new ArgumentNullException("selectorExpression");
        MemberExpression body = selectorExpression.Body as MemberExpression;
        if (body == null)
            throw new ArgumentException("The body must be a member expression");
        OnPropertyChanged(body.Member.Name);
    }

, , , - " ".

:

member this.RunSetStatus() =
    status <- "Reset @" + DateTime.Now.ToString "yy.MM.dd hh:mm:ss"
    base.OnPropertyChanged("Status")

, setter Status.

.

+1

Source: https://habr.com/ru/post/1659052/


All Articles