如何 return 一个对象集合,只有在它们从一个漫长的过程中被填充后

How to return a collection of objects only after they have been filled from a long process

我有一个来自第 3 方 SDK 的对象数据库。他们提供了一种基于事件的方法来搜索事物。我希望搜索内容,并且只在搜索完成后 return 结果。这是我正在使用的伪代码:

Class SearchThings
{
    private Object DatabaseOfDifferentThings;
    
    private List<Thing> _objects = null;
    private SearchSession _search = null;
    private bool _initialized = false;
    
    public SearchThings()
    {
        
    }
    
    Public List<thing> GetFoundThings()
    {
        if (_initialized == false)
        {
            StartSearch();  
        }
        
        return _objects;
    }
    
    private void StartSearch()
    {
        _objects = new List<Thing>();
        _search = DatabaseOfDifferentThings("TypeOfThingToSearchFor");
        _search.ThingAvailable += OnThingAvailable;
        _search.Progress += OnProgress;
        
        _search.StartSearch();
    }
    
    private void OnThingAvailable(Thing thing)
    {
        _objects.Add(thing);
    }
    
    private void OnProgress(int progress)
    {
        if (progress == 100)
        {
            _search.StopSearch();
            _search -= OnProgress;
            _search -= OnThingAvailable;
            
            _initialized = true;
        }
    }

}

我的意图是在完全填充和初始化列表时仅从 GetFoundThings() return。由于搜索机制订阅事件来填充列表,我不确定如何在收集对象时使用异步等待或其他机制来“暂停”。

如有任何帮助,我们将不胜感激。

您可以使用 TaskCompletionSource.

用法示例:

private TaskCompletionSource<object> _tcs = new TaskCompletionSource<object>();

StartSearch 更改为 return Task

private Task StartSearch()
{
    _objects = new List<Thing>();
    _search = DatabaseOfDifferentThings("TypeOfThingToSearchFor");
    _search.ThingAvailable += OnThingAvailable;
    _search.Progress += OnProgress;
    
    _search.StartSearch();
    return _tcs.Task; // return Task that represents future work
}

然后在你的OnProgress命中100时,你可以完成Task

private void OnProgress(int progress)
{
    if (progress == 100)
    {
        _search.StopSearch();
        _search -= OnProgress;
        _search -= OnThingAvailable;
        
        _initialized = true;
        _tcs.SetResult(null);
    }
}

然后你可以这样称呼它:

public async Task<List<Thing>> GetFoundThings()
{
    if (_initialized == false)
    {
       await StartSearch();  
    }
    
    return _objects;
}