.NET Core WCF 连接服务中是否有同步方法? [英] Are there synchronous methods in .NET Core WCF Connected Services?

查看:43
本文介绍了.NET Core WCF 连接服务中是否有同步方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 .NET Core 项目只为 WCF 服务生成异步方法.有没有办法像在常规 .NET 项目中一样使用同步方法?

My .NET Core project is generating only async methods for the WCF service. Is there any way to use synchronous methods like in regular .NET projects?

在常规的 .NET 中,有同步和异步方法,例如:WcfClient.MethodNameWcfClient.MethodNameAsync

In regular .NET there was both sync and async methods like: WcfClient.MethodName and WcfClient.MethodNameAsync

在 .NET Core 中只有 WcfClient.MethodNameAsync

In .NET Core there are only WcfClient.MethodNameAsync

这个问题对我有帮助:C#中如何从同步方法调用异步方法?

但是这个解决方案会导致其他问题.任何想法如何生成同步方法/函数?

But this solution causes other problems. Any ideas how to generate synchronous methods/functions?

推荐答案

检查 这个 GitHub 问题;他们讨论了您可能感兴趣的一些事实.

Check this GitHub issue; they discuss some facts that you may be interested in.

你说得对.我们的 NetCore/Netstandard 支持还不包括 API 的同步实现.请注意,此更改在我们的路线图中作为过渡到 .NetCore 的奇偶项目之一,一旦可用,我们将尽快更新更具体的时间表.

You are right. Our NetCore/Netstandard support does not yet include Sync implementation of the APIs. Please note that this change is on our Roadmap as one of the parity items for the transition to .NetCore and we will update with more specific timelines as soon as it is available.

您能否向我们阐明您对同步方法的需求?总的来说,同步的资源效率比异步低得多,我们不推荐给我们的客户.如果您需要阻止异步调用,您可以随时使用 .GetAwaiter.GetResult().

Can you clarify for us what your need is for the synchronous methods? Overall, sync is much less resource efficient than async and is not something that we recommend to our customers. You can always use .GetAwaiter.GetResult() if you need to block on the async calls.

我们与提供此指导的 CLR 团队进行了一些对话:

We have had some conversations with the CLR team, who provided this guidance:

如果您从库中公开异步端点,请避免公开仅包装异步实现的同步方法.这样做对消费者隐藏了实现的真实性质,应该由消费者决定他们想要如何使用实现.如果消费者选择阻塞等待异步实现完成,这取决于调用者,他们可以睁大眼睛这样做.这对于异步同步"情况比异步同步"情况更重要,因为对于异步同步",它可能导致应用程序出现重大问题,例如挂起.

If you expose an asynchronous endpoint from your library, avoid exposing a synchronous method that just wraps the asynchronous implementation. Doing so hides from the consumer the true nature of the implementation, and it should be left up to the consumer how they want to consume the implementation. If the consumer chooses to block waiting for the asynchronous implementation to complete, that’s up to the caller, and they can do so with their eyes wide open. This is even more important for the "sync over async" case than it is for the "async over sync" case, because for "sync over async," it can lead to significant problems with the application, such as hangs.

.NET Core 团队出于上面列出的原因(资源消耗等)选择不支持真正的同步 api.即使我们实现了真正的同步,它最终也会在某种程度上通过异步同步.出于这个原因,我们认为添加虚假的同步 api 将成为我们的客户的障碍而不是帮助.如果您对此有任何反馈,请告诉我们.pemari-msft 评论了 2017 年 5 月 11 日

.NET Core team has chosen to not support a true sync api for the reasons listed above (resource consumption, etc.) Even if we implement a true sync, it would end up being sync over async at some level. For this reason, we believe that adding fake sync apis would be a hindrance and not a help to our customers. Please let us know if you have any feedback regarding this. pemari-msft commented on May 11, 2017

让我解释一下原理.如果库使用不支持真正同步的库,那么真正同步就不是库的选项,就像我们和 .NET Core 的情况一样.(无论如何,对于进行网络调用的 API 来说,真正的同步有点用词不当,但这是一个不同的讨论.)所以我们有两个选择:创建一个同步异步包装器,或者让调用者来做.但是正如我们所看到的,官方指导和普遍的智慧是应该避免暴露包装器.这是有充分理由的,它类似于避免包装同步调用的异步 API.避免使用此类 API 不仅可以保持 API 表面清洁,还可以避免混淆.客户会认为真正支持同步或异步,并在他们自己的公共接口中公开它,但后来发现底层实现实际上并不支持它!所以我们得出的结论是,在这种情况下最好遵循普遍的智慧.

Let me explain the rationale. True sync is not an option for a library if it is consuming a library that does not support true sync, as is the case for us and .NET Core. (And anyway, true sync is something of a misnomer for APIs that make network calls, but that's a different discussion.) So we have two options: create a sync-over-async wrapper, or let the caller do it. But as we have seen, the official guidance and prevailing wisdom is that exposing a wrapper should be avoided. This is with good reason, and it's similar to avoiding an async API that wraps a synchronous invocation. Avoiding such APIs not only keeps the API surface clean, it also avoids confusion. Customers will think there is true support for sync or async and expose this in their own public interface only to discover later that the underlying implementation doesn't actually support it! So we have concluded that it is best to follow the prevailing wisdom in this case.

您是对的,死锁避免是必不可少的,尤其是在异步同步场景中,所以让我谈谈如何做到这一点.当线程调用异步方法然后阻塞等待结果时,就会出现死锁问题,而异步方法链正在等待线程释放以便它可以继续.解决方案是让 async 方法在不同的上下文中完成它的工作,它不会受到有限线程池的限制.这是在异步方法中使用 ConfigureAwait 在内部完成的,因此避免了库本身内的死锁.

You are correct that deadlock avoidance is essential, especially in sync-over-async scenarios, so let me say a little about how this is done. The deadlock issue arises when a thread calls an async method and then blocks waiting for the result, while the async method chain is waiting for the thread to free up so it can continue. The solution is to have the async method do its work in a different context where it won't be constrained by a limited pool of threads. This is done internally in the async method using ConfigureAwait, so deadlocks are avoided within the library itself.

如果您觉得真正的同步很重要,那么您可以在 https://github.com/提出这一点dotnet/corefx 以获得 .NET Core 支持.

If you feel that true sync is important then you can bring this up at https://github.com/dotnet/corefx to get this supported in .NET Core.

因此,您可以更改项目以避免 Azure 或虚假同步调用.

So you would either change your project to avoid Azure or fake synchronous calls.

然而,在 2018 年,观点发生了变化:

However, in 2018, there was a change in view:

好吧,经过足够的讨论,遵循 HttpWebRequest 我们决定提供同步方法作为同步异步.在我们弃用库的未来版本中的同步 API 之前,这是我们用户的时间缓冲.

Well, after enough discussion, following the lead set by HttpWebRequest we have decided to offer sync methods as sync-over-async. This is a time buffer for our users before we deprecate the sync APIs in future versions of the library.

@copernicus365 ,为了让人们更简单,特别是那些已经在使用该库的人,我们的 Netstandard2.0 支持包括桌面和 Netcore 之间的功能奇偶校验,将保留方法原样,在相同的命名空间/每个服务拆分包的二进制文件(拆分包目前处于预览状态).当然,我们需要回应 .NET 团队在我们的文档中提供的关于转换为异步的好处的指导,并尽可能清楚地表明它是在幕后同步异步.

@copernicus365 , to keep it simpler for people, particularly those who are already using the library, our Netstandard2.0 support which includes the feature parity between desktop and Netcore, will leave the methods as-is, in the same namespace / binary of the split-per-service packages(split packages are in preview at the moment). Naturally, we’ll need to echo guidance in our docs by the .NET team about the benefits of converting to async, and try to make as clear as possible that it’s sync-over-async under the covers.

非常感谢所有花时间参与此主题并向我们提供反馈的人!

Many thanks to everyone who took the time to chime in on this thread and give us feedback!

一个相关说明 - 对于已经在 .NET 桌面上使用同步方法的现有用户,这些也将转向异步同步.我们正在修改代码库以在任何地方(在桌面和 .NET Core 中)使用 HttpClient,这不提供任何类型的真正同步.这是为了避免对所有内容进行单独的实现(一个使用 HttpWebRequest,一个使用 HttpClient),这导致了不同实现之间的许多错误和行为差异.

One related note - for existing people who are already using the sync methods on .NET Desktop, these will also be moving to sync-over-async. We’re modifying the codebase to use HttpClient everywhere (both in desktop and in .NET Core), which doesn’t offer any sort of true sync. This is to get away from having separate implementations of everything (one with HttpWebRequest and one with HttpClient), which has led to many bugs and behavior differences between the different implementations.

2018 年 5 月,.NET Standard 2.0 目标发生了变化.

And the changes landed in the .NET Standard 2.0 target in May 2018.

这篇关于.NET Core WCF 连接服务中是否有同步方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆