1

I have a view-model which is a UDP network browser for my Android and iOS app (fueled by Xamarin). UDP is used to broadcast the active instance of the application and to listen to broadcasts in order to discover other app instances on the local (Wifi) network.

My view-model has property

public AppInstanceList AppInstances
{
get; set;
}

And there is a method

public async Task StartDiscoveringAppInstancesAsync()

which sets up a while loop which keeps on listening via UPD asynchronously:

while(this.networkService != null)
{
    var discoveredInstance = await this.networkService.DiscoverAppInstanceAsync ();
// Omitted: store the discovered instance and add to list of discovered instances.
  this.AppInstances.Add(...);

  // Wait a bit before checking again.
  await Task.Delay(1000);
}

My problem with this method is the return type of Task. Obviously, the method should not be awaited - it is as endless loop and runs until the discovery is stopped.

So should I change it to be void? But this would violate async/await principles where void should only be used for events.

Whenever I encounter a topic like that I'm wondering if my implementation is actually bad design and there's a different and cleaner approach. Or is the user of the view-model just not supposed to await the outcome of the method?

4

1 回答 1

4

我对这个方法的问题是任务的返回类型。显然,不应等待该方法 - 它是无限循环并一直运行直到发现停止。

那么我应该将其更改为无效吗?但这会违反 async/await 原则,其中 void 只应用于事件。

我不建议将此作为一种async void方法。您可以将其保留为async Task,并且仍然保留await它。

虽然Taskwill 永远不会完成,但将其包装在 anawait中仍然会带来好处,例如如果您在永无止境的任务中收到异常,则自动异常传播(在正确的上下文中)。如果您在某个时候选择这样做,这也将允许您通过适当的处理来提供取消。

每当我遇到这样的话题时,我都会想知道我的实现是否真的是糟糕的设计,并且有一种不同且更简洁的方法。还是视图模型的用户不应该等待方法的结果?

在这种情况下,我实际上建议不要将其设为一般的“异步”方法。将其设为异步方法的问题在于,异步方法建议您现在正在初始化一些操作,但最终会完成。“永无止境”的异步方法会让该 API 的用户感到困惑。

在内部,您可能希望保留现有的方法,但通过以下方式公开 API:

public void StartAppInstanceDiscoveryService();
public event ExceptionEventHandler DiscoveryErrorReceived; // To propogate back an exception/error case if this fails?
于 2013-10-14T19:29:40.780 回答