è indubbio che un’interfaccia utente asincrona sia veramente un beneficio per l’utente, basti solo pensare alla bile che consumo io tutti i giorni per colpa di Outlook, ma è altrettanto indubbio che per lo sviluppatore, quindi sempre io :-), il task sia tutto tranne che semplice…
Questa è la “Commit” di base offerta dall’EditorViewModel del mio toolkit:
protected virtual void CommitEdit()
{
    var data = this.EditContext.Entity;
    if( this.IsDirty )
    {
        data = this.DataSource.CommitChanges();
    }

    var dc = this.EditContext.DataPolicy.DataContext;

    var currentState = EntityTransientState.Persistent;
    var state = this.Memento.GetEntityState( this.DataSource );
    if( ( state & EntityTrackingStates.IsTransient ) == EntityTrackingStates.IsTransient )
    {
        currentState = EntityTransientState.Transient;
    }

    var args = new CommitRequestArgs( data, dc, currentState );

    this.Memento.AcceptChanges();
    
    this.EditContext.Commit( args );

    if( this.EditContext.DataPolicy.CommitPolicy == EditorCommitPolicy.HandledByEditor )
    {
        this.OnCommitEdit(args);
    }

    this.OnEditCommited();
}
Fa un sacco di belle cose, di cui parleremo, ma è sincrona alla UI quindi se è complessa e comporta un set oneroso di operazioni sul db costa, renderla asincrona è apparentemente banale:
protected override void CommitEdit()
{
    Action commit = () => base.CommitEdit();

    AsyncWorker.Using( new { Host = this, Action = commit } )
        .Configure( cfg =>
        {
            cfg.Before = e => e.Argument.Host.IsBusy = true;
            cfg.After = e => e.Argument.Host.IsBusy = false;
        } )
        .Execute( e => e.Argument.Action() );
}
In un ViewModel specializzato… ma non è tutto oro quel che luccica e durante una commit può succedere di tutto e se questo di tutto è asincrono è un filino più complesso da gestire.
.m