c# - View 模型中的异步方法 : should this return Task or void?

标签 c# .net async-await

我有一个 View 模型,它是适用于我的 Android 和 iOS 应用程序的 UDP 网络浏览器(由 Xamarin 提供支持)。 UDP 用于广播应用程序的事件实例并收听广播以发现本地 (Wifi) 网络上的其他应用程序实例。

我的 View 模型有属性

public AppInstanceList AppInstances
{
get; set;
}

还有一个方法

public async Task StartDiscoveringAppInstancesAsync()

它设置了一个 while 循环,它通过 UPD 异步监听:

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);
}

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

那么我应该把它改成void吗?但这会违反 async/await 原则,其中 void 应该只用于事件。

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

最佳答案

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.

我不建议将其设为 async void 方法。您可以将其保留为 async Task,并仍然await

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

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?

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

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

public void StartAppInstanceDiscoveryService();
public event ExceptionEventHandler DiscoveryErrorReceived; // To propogate back an exception/error case if this fails?

关于c# - View 模型中的异步方法 : should this return Task or void?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19367751/

相关文章:

c# - 以编程方式删除文件并将其上传到 Azure Web 应用本地存储

c# - TCPClient 异步/等待 C#

c# - 语言真的依赖于图书馆吗?

c# - SQL Server 断开连接导致连接池问题

用于并发编程的 .NET 语言

c# - async static Task<T> someMethod() 与 static async Task<T> someOtherMethod() 之间有什么区别

javascript - 为什么 async/await 会打破 $http.get/angular 摘要循环?

c# - 如何使用NEST 7.4.1删除索引?

c# - 通过 OpenXML SDK 插入时如何保持当前样式?

c# - 由于语言要求,如何在单独的线程上打开表单