Search Unity

Async and Await

Discussion in 'VR' started by Chrissteven81, Aug 29, 2016.

  1. Chrissteven81

    Chrissteven81

    Joined:
    Aug 29, 2016
    Posts:
    2
    I am working with some DLLs that I cannot change in this case it is the Microsoft Band SDK. I have wrapped all the uwp specific code in compiler directives for NetFX_CORE and I have all the appropriate references/capabilities in both the Assembly_csharp project and the windows holographic project. I have tried 3 different methods all achieving the same results.

    1st method: async start with await keywords
    2nd method: FunctionAsync().GetAwaiter().GetResult();
    3rd method: Start => initialize Tasks, Update check if task is complete and if it is then process result

    All three succeed on short running processes and fail on long running processes.

    Example:

    Code (CSharp):
    1. _bands = await BandClientManager.Instance.GetBandsAsync(); //Retrieves list of devices
    2. _bands = BandClientManager.Instance.GetBandsAsync().GetAwaiter().GetResult(); //Passes
    3.  
    4. _client = await BandClientManager.Instance.ConnectAsync(_bands[0]); //Fails with "A Method was called at an unexpected time"
    5.  
    6. _client = BandClientManager.Instance.ConnectAsync(_bands[0]).GetAwaiter().GetResult(); //Fails with "A Method was called at an unexpected time"
    even method 3 which I figured would let the task keep running and just catch it when it is complete also faults.

    I am looked and cant seem to find anyone else having this problem. I saw an app in the WS that gets around it but I cant seem to figure out how. Anyone have any suggestions?
     
  2. Waterine

    Waterine

    Joined:
    Jul 27, 2016
    Posts:
    6
    All 3 methods should work. It is hard to tell without looking at your actual code. Can you share a mininum repro?
     
  3. Unity_Wesley

    Unity_Wesley

    Unity Technologies

    Joined:
    Sep 17, 2015
    Posts:
    558
    Hello,

    Can you share the script or code on how you are using this? Would be Helpful to have more information to debug the issue.

    Thank you,
    Wesley
     
  4. Chrissteven81

    Chrissteven81

    Joined:
    Aug 29, 2016
    Posts:
    2
    Here is a Vanilla attempt directly from the Microsoft Band SDK Docs. BTW Thanks I have spent several weeks off and on trying to solve this problem. I stripped out the try catch for simplicity.


    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. #if NETFX_CORE
    4. using System;
    5. using System.Collections;
    6. using System.Collections.Generic;
    7. using System.Linq;
    8. using System.Threading.Tasks;
    9.  
    10. //Imported from the Microsoft BAND SDK
    11. using Microsoft.Band;
    12. using System.Diagnostics;
    13. #endif
    14.  
    15. public class BandManager : MonoBehaviour
    16. {
    17.  
    18. #if NETFX_CORE
    19.     private IBandInfo[] _bands;
    20.     private IBandClient _client;
    21. #endif
    22.  
    23.     #if NETFX_CORE
    24.     // Use this for initialization
    25.     async void Start ()
    26.     {
    27.         _bands = await BandClientManager.Instance.GetBandsAsync();
    28.  
    29.         var band = _bands.First();
    30.         //Code Breaks after waiting at this line, Same code works in uwp XAML app.
    31.         _client = await BandClientManager.Instance.ConnectAsync(band);
    32.     }
    33.     #endif
    34.  
    35.     // Update is called once per frame
    36.     void Update ()
    37.     {
    38.    
    39.     }
    40. }
     
  5. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    This doesn't really seem to be related to Unity: it's just using the API incorrectly somehow. Maybe you're calling it on the wrong thread? I'm not very familiar with that SDK so I'm not sure why it fails.
     
  6. JanMoser_78

    JanMoser_78

    Joined:
    Oct 3, 2016
    Posts:
    1
    have you tried to check if band has a correct value?
    the await on 27 returns control to the main thread which can do some things that break the execution of line 31
    if would generally use _bands.FirstOrDefault() on 29 to make sure it won't crash if bands is empty...and then check for null before you invoke the connect....additionally if would also try to lock the _bands not to generate a race-condition occuring (depending on what you do with Start....)

    and have you tried this already?

    var bands = await BandClientManager.Instance.GetBandsAsync();
    if (!bands.Any())
    {
    //apply some logic here when there is no band detected....
    return;
    }
    _band = await BandClientManager.Instance.ConnectAsync(bands[0]);