【问题标题】:Is this the correct async approach for waiting for a property to be set?这是等待设置属性的正确异步方法吗?
【发布时间】:2016-08-03 18:33:43
【问题描述】:

我有一个由后台操作设置的类属性。这是我读取该属性值的方法。这个想法是在返回 null 之前等待一段合理的时间,因为这意味着仍有工作即将完成

public async Task<Entity> GetEntityAsync()
{
    int tries = 0;
    while (_entity == null && tries < 2)
    {
        await Task.Delay(100);
        tries++;
    }

    return _entity;
}

那我就这样用

var entity = await entityManager.GetEntityAsync();

这种方法正确还是有更好的选择?

编辑

设置_entity 的后台操作是通过事件报告数据可用的第三方组件。我想将事件方法转换为 async/await 方法。原因是

  • 这种方法在很多地方都使用过(我正在重构),它还没有为面向事件的方法做好准备。
  • 面向事件的方法实施起来更加复杂。我只是想确保我不会挂起主线程,99% 的情况下,_entity 在第一次拍摄时会有一个不同于 null 的值。

【问题讨论】:

  • _entity 是如何处理的?你在哪里设置它的价值?
  • 你的属性设置器不能在设置后触发事件吗?此外,如果您等待完成它,它并不是真正的异步
  • @EhsanSajjad:有一个后台线程最终会设置它。主要是想知道那个方法的逻辑有没有bug,对我的async/await技能不是很自信
  • @musefan:不想处理事件,我想调用一个方法并获取值(如果有)
  • @StackOverflower 这个问题无法解释为什么你需要这样做。

标签: c# async-await


【解决方案1】:

您说您的数据源使用事件返回_entity。事件很容易连接到TaskCompletionSource。考虑:

public Task<Data> GetDataAsync()
{
  var tcs = new TaskCompletionSource<Data>();

  dataSource.DataReturned += d => tcs.SetResult(d);

  return tcs.Task;
}

现在你有一个不错的小异步方法连接到你的数据源事件。

当然,这只是一个非常简单的例子,它做了很多假设,没有错误处理等,但它应该能让你找到一个好的解决方案。如果您有活动,则无需轮询:)

【讨论】:

  • 您需要取消订阅 dataSource.DataReturned 以避免内存泄漏。
  • @Ive 是的,这是假设之一——dataSource 不是持久的。不仅仅是内存泄漏,在这种情况下还有更重要的问题:)
【解决方案2】:

你的方法不可靠。

为此,您应该在 GetEntityAsync() 方法中等待 entityManager.GetEntityAsync() 方法:

public async Task<Entity> GetEntityAsync()
{
    _entity = await entityManager.GetEntityAsync();
    return _entity
}

【讨论】:

  • 在属性 getter 上等待是无效的,这只是编译时不允许的
  • @StackOverflower 然后不要让它成为一个属性;让它成为一种方法。
  • @Servy:这就是我所拥有的,一种方法(GetEntityAsync)。请检查我的编辑
  • 我们正在等待方法而不是属性获取器
  • @Ehsan Sajjad:正确,但在您发布之前,您建议等待属性获取器,这就是为什么我说我不能这样做
【解决方案3】:

定义你的 _entity 像:

TaskCompletionSource<Entity> _entity =  _new TaskCompletionSource<Entity>();

并在第 3 次这样设置。派对活动:

_entity.TrySetResult(xxxx);

然后像这样使用它:

public async Task<Entity> GetEntityAsync()
{
    Entity result = await _entity.Task;
    _entity = _new TaskCompletionSource<Entity>();
    return result;
}

【讨论】:

    猜你喜欢
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2020-08-01
    • 2014-12-17
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多