2

How can I pass the framworkElement and use an async keyword too in this code?

SaveImage = new RelayCommand<FrameworkElement>(frameworkElementForPrint =>  
{
    StorageFile file = await PickImageFileToSave();
    SaveVisualElementToFile(frameworkElementForPrint, file);
});

Becaue now the await can not be used...

Krekkon
  • 1,349
  • 14
  • 35
  • 2
    Assuming that that type wasn't specifically designed to support `async` lambdas, the answer most likely is "you can't". (At least not in a meaningful way. You could make it compile, but it wouldn't work as intended.) – Servy Feb 07 '14 at 21:13

1 Answers1

6

I recommend that you factor all your logic into a separate method, as such:

public async Task SaveImageAsync(FrameworkElement frameworkElementForPrint)
{
  StorageFile file = await PickImageFileToSaveAsync();
  await SaveVisualElementToFileAsync(frameworkElementForPrint, file);
}

Then wrap this into the RelayCommand:

SaveImage = new RelayCommand<FrameworkElement>(async arg => { await SaveImageAsync(arg); });

This separation allows you to unit test your SaveImageAsync logic (assuming of course that you refactor with proper abstractions).

This MSDN article has a little more detail on async commands.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • What's the purpose of this lambda? Why not write `new RelayCommand(SaveImageAsync)` if you've made the named method? – Servy Feb 07 '14 at 21:37
  • 2
    The lambda converts the `async Task` into an `async void`. Which of course should be avoided, but in this case (implementing `ICommand.Execute`), it's *logically* an event handler. – Stephen Cleary Feb 07 '14 at 21:40
  • I will try it in a minute, but looks like good. I just cant understand, why not working with two method in lamba, but works with one named method – Krekkon Feb 07 '14 at 21:42
  • 1
    @Krekkon Either would work. Stephen is suggesting this change merely as a matter of best practice, not because this is a requirement. – Servy Feb 07 '14 at 21:43
  • I got it, my question is just talk about: in my original example i try write async before frameworkElementForPrint ,but the compiler alarmed me. So i can got it why works this and why doesnt in my example. :)) – Krekkon Feb 07 '14 at 22:17
  • By the way i tried this out and its works. Only suggestion is take an async before the Task. :) – Krekkon Feb 07 '14 at 22:17