简体   繁体   中英

How to safely make sure an async method in C# is completed?

please excuse the possibly stupid question. Is there a difference between the two code snippets?

Example 1: Running an async method CapturePhotoToStorageFileAsync in a synchronous method

class Core
{
    async void ProcessCommand(Command cmd)
    {
        // Do some stuff
        await JobManager.ReportTrigger(cmd.TriggerID);
        SendCommand(Command reply);
    }
}

class JobManager
{
    async Task ReportTrigger(Int32 triggerID)
    {
        await Task.Delay(300);
        Webcam.CapturePhotoToFile();
        await Task.Delay(100);
    }
}

class WebCam
{
    void CapturePhotoFile()
    {
        m_MediaCapture.CapturePhotoToStorageFileAsync( ImageEncodingProperties.CreateJpeg(), file );
    }
}

Example 2: Running the async method CapturePhotoToStorageFileAsync as a task:

class Core
{
    async void ProcessCommand(Command cmd)
    {
        // Do some stuff
        await JobManager.ReportTrigger(cmd.TriggerID);
        SendCommand(Command reply);
    }
}

class JobManager
{
    async Task ReportTrigger(Int32 triggerID)
    {
        await Task.Delay(300);
        await Webcam.CapturePhotoToFile();
        await Task.Delay(100);
    }
}

class WebCam
{
    async Task CapturePhotoFile()
    {
        await m_MediaCapture.CapturePhotoToStorageFileAsync( ImageEncodingProperties.CreateJpeg(), file );
    }
}

I really need to make sure that the Call "SendCommand(Command reply)" is being executed AFTER the webcam picture has been saved. Which method is more suitable for this purpose?

Thanks in advance and best regards!

EDIT:

According to the comments received i am currently thinking about this implementation:

class Core
{
    async Task ProcessCommandAsync(Command cmd)
    {
        // Do some stuff
        await JobManager.ReportTriggerAsync(cmd.TriggerID);
        SendCommand(Command reply);
    }
}

class JobManager
{
    async Task ReportTriggerAsync(Int32 triggerID)
    {
        await Task.Delay(300);
        await Webcam.CapturePhotoToFileAsync();
        await Task.Delay(100);
    }
}

class WebCam
{
    async Task CapturePhotoFileAsync()
    {
        await m_MediaCapture.CapturePhotoToStorageFileAsync( ImageEncodingProperties.CreateJpeg(), file );
    }
}

I would really appreciate if somebody could ensure me the intended behaviour for this implementation. Is it really assured that the command in Core.ProcessCommandAsync is send AFTER the picture has been saved?

@Dai: Thanks for your feedback. I merged my answer into my first posting. Sorry for the trouble.

There are a few rules that make async easier to get right.

  1. Async functions return Task or Task<> (don't use void)
  2. Async functions are named with Async on the end (MyFuncAsync) - this reminds you to call await on those functions, see rule 3.
  3. Await any async functions (unless you want them to run in parallel)
  4. Don't break these rules.

Keeping to these rules can be hard, if you have already broken them, and have to refactor your program.

(there are lots of exceptions to these rules, but if you don't know what you are doing, then try to keep to the rules).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM