0

I have an async function call myAsyncfuntion() which look like that

public async Task TakePhotoBasicAndSaveAndDisplayUWP()
{
    var photoImplementation = new MediaCaptureImplementation();
    photoImplementation.TakePhotoTexture2DAsync();
    // Some code here...

    await photoImplementation.SavePhotoToPicturesLibraryAsync();
}

Now I would like to call this function from another non async function so I do like this. Basically I attact a button to TakePhotoBasicAndSaveAndDisplay() and whenever the button got clicked, the function will start the async function inside. But the async function seem not to be called.

public void TakePhotoBasicAndSaveAndDisplay()
{
   #if WINDOWS_UWP
    var task = Task.Run(async () => await TakePhotoBasicAndSaveAndDisplayUWP());
   #endif
}

Could anyone help me ? I am working with unity

user7112196
  • 87
  • 2
  • 9
  • 5
    "How to call async function with await inside a non async function in c#?" - you don't; it will hurt you *every time*, and is an anti-pattern called "sync over async" - it is almost always a very bad idea to try and make this work, and you'll regret it. Make the caller `async`, basically. – Marc Gravell Apr 02 '19 at 15:23
  • 2
    If that's an event handler then you typically make them `async void` – juharr Apr 02 '19 at 15:24
  • 1
    This SO answer might help, scroll down a bit to find the C# 7.2 version - https://stackoverflow.com/questions/9343594/how-to-call-asynchronous-method-from-synchronous-method-in-c – vscoder Apr 02 '19 at 15:25

3 Answers3

1

You do this only if you don't want to await it and "don't care" about the outcome you could make it async void

public async void TakePhotoBasicAndSaveAndDisplayUWP()
{
    var photoImplementation = new MediaCaptureImplementation();
    photoImplementation.TakePhotoTexture2DAsync();
    // Some code here...

    await photoImplementation.SavePhotoToPicturesLibraryAsync();
}

than you can call it like

    public void TakePhotoBasicAndSaveAndDisplay()
    {
#if WINDOWS_UWP
       TakePhotoBasicAndSaveAndDisplayUWP();
#endif
    }

(see this good tutorial)

derHugo
  • 83,094
  • 9
  • 75
  • 115
  • 3
    it is OK-ish for an event-handler to be `async void`, but ... looks to me like `TakePhotoBasicAndSaveAndDisplayUWP` should be `async Task`, with `TakePhotoBasicAndSaveAndDisplay()` using `await TakePhotoBasicAndSaveAndDisplayUWP();` - unless there is literally no alternative – Marc Gravell Apr 02 '19 at 15:27
  • well there is none if the OP wants to call it from a non-async method – derHugo Apr 02 '19 at 15:28
1

As Marc commented, the only correct answer to "how do I call an asynchronous method from a synchronous method" is "you don't".

But the async function seem not to be called.

It is certainly being called, but it's possible that it may not be working correctly because it is not on the main UI thread. Task.Run is executing it on a thread pool thread. Also, I suspect that the task in var task = Task.Run(async () => await TakePhotoBasicAndSaveAndDisplayUWP()); is never awaited, so any exceptions from TakePhotoBasicAndSaveAndDisplayUWP would be ignored. I.e., exceptions stating that some API must be called from the main UI thread and not a thread pool thread.

I attact a button to TakePhotoBasicAndSaveAndDisplay

If TakePhotoBasicAndSaveAndDisplay is in fact an event handler, then you can use async void:

public async void TakePhotoBasicAndSaveAndDisplay()
{
  #if WINDOWS_UWP
  await TakePhotoBasicAndSaveAndDisplayUWP();
  #endif
}
Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
-2

You could always call the async method with .Wait() at the end.

myAsyncfuntion.Wait();

It kinda ruins the whole async thing. The method will block synchronously until the task completes.

You could check this response for more details.

Cosmin
  • 124
  • 1
  • 5