3

I have following implementation and added a Async Task<bool> operation in the ChangeDate() method, previously it was just bool.

In the following line if (!ChangeDate())

Operator ! cannot be applied to operand of type Task

 public DateTime Date
 {
    get { return _date; }
    set
    {
      if (!ChangeDate())
      {
         return;
      }

      _date = value.Date;

    }
} 

private async Task<bool> ChangeDate()
{
  if (IsSave)
  {
     await Mvx.Resolve<IUserDialogs>().ConfirmAsync(new ConfirmConfig
     {
        Message = "Are you sure ?",
        OnConfirm = b =>
        {
            if (b)
            {
              Save();
            }
         }
      });
   }
   return true;
 }
casillas
  • 16,351
  • 19
  • 115
  • 215
  • 1
    Might want to review how to call async methods, because it returns a task, not bool, you have to run the task and get the result. – Ron Beyer Feb 12 '18 at 23:57
  • could you please illustrate with an example? – casillas Feb 12 '18 at 23:58
  • See: [How would I run an async Task method synchronously?](https://stackoverflow.com/questions/5095183/how-would-i-run-an-async-taskt-method-synchronously) – Ron Beyer Feb 13 '18 at 00:17
  • 2
    I'd really suggest rewriting this - displaying a UI dialog in a setter seems like a horrible design – Jason Feb 13 '18 at 00:43
  • I am not displaying the UI dialog in a setter, I am just checking whether or not Date is being changed in the setter method. what do you propose? – casillas Feb 13 '18 at 05:41
  • Please mark as answer if you agree with the answer below,. – sjb-sjb Feb 16 '18 at 12:35

2 Answers2

11

Found this answer: How to make an Asynchronous Method return a value?

You'll need to make an async helper method, and call that instead of calling just your setter, because as @Ron Beyer points out, the await call will not work in a property.

Replace:

if(!ChangeDate())

With:

if( !(await ChangeDate()) )
user7396598
  • 1,269
  • 9
  • 6
  • 2
    Await can only be used in async methods, which the property is not. – Ron Beyer Feb 12 '18 at 23:59
  • Oh dang. It won't work the way he currently has it written. – user7396598 Feb 13 '18 at 00:02
  • I have updated the answer so that it will in fact work, and is a simple implementation. – user7396598 Feb 13 '18 at 00:12
  • It will work *in an `async` method* but it will not work for the OP because it is being called from a property. This would require an architecture change (changing a property to an async method) which just moves the problem higher up the chain. – Ron Beyer Feb 13 '18 at 00:18
  • Moving it out of the property is the way to fix it, and what was suggested. Changing Prop = blah; to SetProp(); is not difficult to do. Nor is defining async SetProp, especially given he has the rest of the code he wants to execute already written. If he puts it into an async method and it still does not work he should receive a different error to debug regarding why he cannot make an async call, not that he is getting an invalid return. – user7396598 Feb 13 '18 at 16:55
4

Maybe you want something like this ... ?

public DateTime Date { get; private set; }

public Task SetDateIfUserConfirmsAsync( DateTime proposedDate) 
{ 
     var confirmConfig = new ConfirmConfig() {
         Message = "Are you sure ?",
         OnConfirm = b => { if (b) { this.Date = proposedDate; } }
     }
     await Mvx.Resolve<IUserDialogs>().ConfirmAsync( confirmConfig);
}

You haven't said what UI you are using but likely you are in a button callback, which has a synchronous signature (void return). In that case you want to make sure that you catch any exceptions because otherwise you will never see them (exceptions are not propagated back to the caller of an async void method). A bit like this:

public async void OnButtonClick()
{ 
    try {
        DateTime proposedDate = ...;
        await SetDateIfUserConfirmsAsync( proposedDate)
    } catch (Exception e) {
        // display or log the exception
    }
 }

P.S. On the error you saw, "operator ! cannot be applied to operand of type Task<bool>", it was because you did not await the task. If t has type Task<bool> then "await t" has type bool.

sjb-sjb
  • 1,112
  • 6
  • 14