Search code examples
c#unity-game-engineasynchronousasync-await

Run expensive operation in the background without awaiting a result


I have done my research on the topic, but I still do not fully understand the async and await blocks in C# as a lot of people suggest different functions and approaches. Still, I can't find anything close to what my goal is.

I am working in Unity and want to send some screenshots over a socket to another application. Unity requires the screenshot to be taken by the main thread, as it is not thread-safe. The costly operation is the sending of the frame, which I though should be better handled by a background thread. This is done in a while(running) loop.

Maybe the easiest way is to just create a new Thread and pass the frame for processing there, but I wanted to know if there is an efficient way to do this with async Task.

First I tried to create an async Task, but I leant that without the await the code is not really parallel. The issue I am facing is, that I do not want the main thread to block and do not require any result from the Task to continue.

This is the final code I am using:

private static async Task sendSceenshot(PushSocket socket, byte[] frame)
{
  await Task.Run(() => socket.TrySendFrame(frame));
}

private static void Screenshot()
{
  while (isRunning)
    {
      yield return new WaitForSeconds(1f);
      
      // Take the screenshot...
      // [...]
 
      // Send the frame in the background without blocking the main thread
      sendSceenshot(screenSocketWide, currentFrame);

      // Reset and prepare for next frame
      // [...]
}

Solution

  • You can just use the Task.Run() method for this. It utilizes the thread pool for you, so you don't have to deal with threads by hand.

    private static void Screenshot()
        {
            
            //set up socket and frame
            
            //the key part
            await Task.Run(() => socket.TrySendFrame(frame));
        }
    

    See this to understand the differences between Thread and Task more in depth.

    I'm not sure what you meant by "this does not terminate the program", could you elaborate?