.net – 使用Task.Wait()代码包装Async / Await IAsyncOperation
我目前正在尝试将相当数量的现有同步代码移植到WinRT.
作为其中的一部分,我遇到了现有代码的问题,希望某些操作是同步的 – 例如用于文件I / O. 为了使这个现有代码适应WinRT中的IAsyncOperation样式API,我使用了一种使用扩展方法包装IAsyncOperation的技术,如: namespace Cirrious.MvvmCross.Plugins.File.WinRT { public static class WinRTExtensionMethods { public static TResult Await<TResult>(this IAsyncOperation<TResult> operation) { var task = operation.AsTask(); task.Wait(); if (task.Exception != null) { // TODO - is this correct? throw task.Exception.InnerException; } return task.Result; } } } 从MvvmCross WinRT ExtensionMethods开始 – 使用与IAsyncAction类似的方法 这些包装器似乎有效 – 它们允许我在同步代码中使用Async方法,如: public IEnumerable<string> GetFilesIn(string folderPath) { var folder = StorageFolder.GetFolderFromPathAsync(ToFullPath(folderPath)).Await(); var files = folder.GetFilesAsync().Await(); return files.Select(x => x.Name); } 我知道这并不是真正符合WinRT的精神;但我希望这些方法通常只能在后台线程上调用;我写这篇文章的目的是让我的代码跨平台兼容 – 包括那些尚未支持await-async的平台和/或尚未准备好跳转的开发人员. 所以……问题是:使用这种类型的代码我运行的风险是什么? 作为第二个问题,有没有更好的方法可以实现文件I / O等领域的代码重用? 解决方法
首先,我认为您的方法可以改写为:
public static TResult Await<TResult>(this IAsyncOperation<TResult> operation) { return operation.AsTask().Result; } 如果任务尚未完成,则调用结果将同步等待.如果失败,它将抛出AgreggateException.我认为像你一样抛出InnerException是个坏主意,因为它会覆盖异常的堆栈跟踪. 关于你的实际问题,我认为使用Wait()和异步代码的最大危险是死锁.如果你在UI线程上启动一些内部使用await的操作,然后在同一个线程上使用Wait()等待它,你将遇到死锁. 如果你没有在UI线程上等待,那么这并不重要,但如果可能的话,你仍然应该避免它,因为它违背了整个异步的想法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Docker Client (another java docker client api)
- java – 包装jar无效聚合器项目需要pom作为包装
- 字符串类型的变化
- java – Hibernate – hibernate.hbm2ddl.auto = validate
- java – 用于复杂数学表达式的高级标记生成器
- 为什么javax.naming.NamingException出现在这里?
- JSP Response.addCookie()方法:添加cookie对象
- Java 读取汉字全拼简写
- 六、垃圾回收_判断对象是否存活算法_引用计数法详解
- java – 无法从android appf中的youtube api检索到优质视频