У меня есть функция, которая загружает несколько ресурсов через асинхронный режим, и я хочу вызвать действие onComplete
, когда все ресурсы загружены, но в настоящее время, учитывая природу асинхронности, я не уверен, как заставить мою функцию делать это, поскольку я относительно новичок. программированию в асинхронном режиме.
public void Load(Action onComplete)
{
foreach (var kvp in _db)
{
var key = kvp.Key;
var assetRef = kvp.Value;
assetRef.LoadAssetAsync<TAsset>().Completed += handle =>
{
if (handle.Status == AsyncOperationStatus.Succeeded)
_loadedAssets.Add(key, handle.Result);
//check if all assets have been loaded and then call onComplete
};
}
}
🤔 А знаете ли вы, что...
C# обеспечивает возможность создания многопоточных приложений с помощью пространства имен System.Threading.
Вам следует использовать Microsoft Reactive Framework (он же Rx) — NuGet System.Reactive
и добавить using System.Reactive.Linq;
— тогда вы сможете сделать это:
public void Load2(Action onComplete)
{
(
from kvp in _db.ToObservable()
let key = kvp.Key
let assetRef = kvp.Value
let assetLoader = assetRef.LoadAssetAsync<TAsset>()
from handle in
Observable
.FromEvent<Action<AssetHandle>, AssetHandle>(
h => assetLoader.Completed += h,
h => assetLoader.Completed -= h)
.Take(1)
where handle.Status == AsyncOperationStatus.Succeeded
select new { key, handle.Result }
)
.Subscribe(
x => _loadedAssets.Add(x.key, x.Result),
() => onComplete());
}
Теперь это должно сработать. Мне пришлось перепроектировать некоторые типы, но, думаю, я с этим справился. Состояние гонки все еще существует в вашем коде.