Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Metro应用程序中的异步调用链接_C#_User Interface_Asynchronous_Microsoft Metro_Async Await - Fatal编程技术网

C# Metro应用程序中的异步调用链接

C# Metro应用程序中的异步调用链接,c#,user-interface,asynchronous,microsoft-metro,async-await,C#,User Interface,Asynchronous,Microsoft Metro,Async Await,我对Metro dev很陌生,我只希望我能以一种可以理解的方式表达我的问题 实际上,我正在将旧应用程序的一部分移植到Metro。逻辑部分是一个独立的项目(可移植库),它应该用于1)旧WPF应用程序和2)新Metro应用程序。基本逻辑是相同的,但某些子系统(例如文件操作管理器)必须采用不同的编码方式,即Metro的异步方式 我的问题是:我是否必须将调用方调用的整个方法链重写为新的异步范式?假设我有一个由4个方法组成的链,从方法a=Metro UI event async handler开始(对我来

我对Metro dev很陌生,我只希望我能以一种可以理解的方式表达我的问题

实际上,我正在将旧应用程序的一部分移植到Metro。逻辑部分是一个独立的项目(可移植库),它应该用于1)旧WPF应用程序和2)新Metro应用程序。基本逻辑是相同的,但某些子系统(例如文件操作管理器)必须采用不同的编码方式,即Metro的异步方式

我的问题是:我是否必须将调用方调用的整个方法链重写为新的异步范式?假设我有一个由4个方法组成的链,从方法a=Metro UI event async handler开始(对我来说,将其编码为async void是有意义的,因为它是最重要的fire&forget事件),通过放置在应用程序不同层中的接下来2个方法(B和C),一直到包含“await CreateFileAsync”方法(由Microsoft创建为async)的方法D

现在:异步CreateFileAsync方法应该用wait调用。这迫使我也使方法D异步。要从C调用方法D,从B调用方法C,从A调用方法B,我必须将所有A、B和C重写为异步等待样式吗

我能感觉到我错过了更深层次的知识,所以我试图教育自己,但同时我想在这里试试我的运气

我必须重写大部分代码吗?我上面的陈述有错吗


首先非常感谢,Hans

我建议您将便携库重写为异步的。它不像以前那么糟糕了;微软在
async
/
wait
上下了很大功夫,使同步代码转换为异步代码变得尽可能容易。我预计在不久的将来,很多其他人也会这样做,而R#可能会实现“make async”重写

混合使用同步和异步代码时存在不明显的缺陷——请参阅Stephen Toub的上一篇博客文章。出于这个原因,我认为将异步操作公开为异步API(将同步操作公开为同步API)更为简洁

更新:如果希望同步代码调用异步代码,则可以使用中的
Task.waitanduncapeException
扩展方法。但是,您仍然存在Stephen Toub帖子中提到的问题,即:

  • 如果库没有在任何地方使用
    ConfigureAwait(false)
    ,则可能会死锁
  • 如果线程池中的线程数达到最大值,也可能会死锁

  • (2) 现在已经不那么普遍了,但是(1)是一种真正的可能性。它经常被那些刚刚测试
    async
    的人使用,所以他们会将它与同步代码混合使用。

    我建议您将便携库重写为异步。它不像以前那么糟糕了;微软在
    async
    /
    wait
    上下了很大功夫,使同步代码转换为异步代码变得尽可能容易。我预计在不久的将来,很多其他人也会这样做,而R#可能会实现“make async”重写

    混合使用同步和异步代码时存在不明显的缺陷——请参阅Stephen Toub的上一篇博客文章。出于这个原因,我认为将异步操作公开为异步API(将同步操作公开为同步API)更为简洁

    更新:如果希望同步代码调用异步代码,则可以使用中的
    Task.waitanduncapeException
    扩展方法。但是,您仍然存在Stephen Toub帖子中提到的问题,即:

  • 如果库没有在任何地方使用
    ConfigureAwait(false)
    ,则可能会死锁
  • 如果线程池中的线程数达到最大值,也可能会死锁

  • (2) 现在已经不那么普遍了,但是(1)是一种真正的可能性。这是那些正在测试
    async
    的人经常做的,所以他们将它与同步代码混合使用。

    嗨,Stephen,谢谢你的回答。我几个小时前读过那篇文章,但我会用新的眼光再看一遍。问题是,这是相当多的代码。最初,我实现了MVC模式(当时不知道MVVM),它给了我很多控制器中的一个或两个线性方法。我必须全部重写吗?如果我能决定不。。。如何从同步C方法调用异步D方法?如果我决定重写所有。。。在另一篇文章()中,我发现对于这样的一行程序,Task.FromResult应该优先于classic await。在这一点上,你同意那篇文章吗?@Hans-他写了那篇文章,所以我当然希望如此:)Stephen-任务。在Hans链接到的2月份博客帖子中,FromResult似乎让我感到困惑-你只能在已经有结果的情况下使用它(当然),那么为什么这样的方法甚至会返回Task而不是TreResult?如果你确定你已经有了预计算的值(例如,来自内存缓存),并且需要保留任务作为“缓存未命中”案例的响应,我可以看到它,但这似乎不是博客文章所指的-你能用一个示例方法详细说明吗?@James:缓存就是一个很好的例子。其他时候,方法只需执行快速检查并返回一个常量,就可以为复杂情况(例如,异常情况)保存真正的
    async
    实现。或者,如果它只是在调用另一个
    async
    方法之前进行一点(同步)预处理。或者,如果您正在重写基类中的
    Task
    方法,但有一个同步实现。我会澄清这篇博文。嗨,斯蒂芬,谢谢你的回答。我几个小时前读过那篇文章,但我会用新的眼光再看一遍。问题是,这是相当多的代码。最初,我实现了MVC模式(当时不知道MVVM),它给了我很多控制器中的一个或两个线性方法。