Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Make coroutine wait for async inside a try clause

Discussion in 'Scripting' started by nir_unity198, Oct 13, 2022.

  1. nir_unity198

    nir_unity198

    Joined:
    Jun 13, 2022
    Posts:
    5
    I hade this methode inside a coroutine
    wrapper.PutToDBAsync(newVenue);


    I've recieved the warning
    "Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call."

    in most places I've changed it to
    Code (CSharp):
    1.                 Task task = wrapper.PutToDBAsync(newEntry);
    2.                 yield return new WaitUntil(()=>task.IsCompleted);
    And it worked fine.

    But in 1 place I wanted to perform a 'try' around it

    Code (CSharp):
    1.             try
    2.             {
    3.                 if (newEntry != null)
    4.                 {
    5.                     wrapper.PutToDBAsync(newEntry);
    6.                 }
    7.                 else
    8.                 {
    9.                     GameStaticData.LogError($"new {entry.name} is null");
    10.                 }
    11.             }
    And I cannot yield inside a 'try' clause.

    Any Idea how to bypass it?
     
  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    Why do you have to call return yield inside the try? Cant you just put it outside? Maybe im missing why this is a problem.
     
  3. rubcc95

    rubcc95

    Joined:
    Dec 27, 2019
    Posts:
    222
    Idea here with some extension methods:
    Code (CSharp):
    1.  
    2. using System;
    3. using System.Collections;
    4. using UnityEngine;
    5.  
    6. public class ExampleClass: MonoBehaviour
    7. {
    8.     readonly int[] _values = new int[] { 1, 2, 3, 4 };
    9.  
    10.     private void Update()
    11.     {
    12.         //Right click to start a coroutine which won't catch an error
    13.         if (Input.GetMouseButtonDown(0))
    14.             StartCoroutine(Routine(4).TryYield((error) => Debug.LogWarning($"Error catched: {error.Message}")));
    15.  
    16.         //Right click to start a coroutine which will catch an error
    17.         if (Input.GetMouseButtonDown(1))
    18.             StartCoroutine(Routine(5).TryYield((error) => Debug.LogWarning($"Error catched: {error.Message}")));
    19.     }
    20.  
    21.     IEnumerator Routine(int length)
    22.     {
    23.         for(int i = 0; i < length; i++)
    24.         {
    25.             Debug.Log(_values[i]);
    26.             yield return new WaitForSeconds(0.5f);
    27.         }
    28.     }
    29. }
    30.  
    31.  
    32.  
    33. public static class TryYieldExtension
    34. {
    35.     public static IEnumerator TryYield(this IEnumerator enumerator, Action<Exception> catchCallback = null) => TryYield<Exception>(enumerator, catchCallback);
    36.     public static IEnumerator TryYield<T>(this IEnumerator enumerator, Action<T> catchCallback = null) where T : Exception
    37.     {
    38.         while (true)
    39.         {          
    40.             try
    41.             {
    42.                 if (!enumerator.MoveNext())              
    43.                     break;                              
    44.             }
    45.             catch (T error)
    46.             {
    47.                 catchCallback?.Invoke(error);
    48.                 yield break;
    49.             }
    50.             yield return enumerator.Current;
    51.         }      
    52.     }
    53. }