我已经将所有调用WCF调用的代码包装在一个using语句中,以为该对象将被正确放置.当我在谷歌搜索异常"位于...的Http服务太忙"时,我发现这个链接http://msdn.microsoft.com/en-us/library/aa355056.aspx说不应该使用using语句键入的代理.这是真的吗?我想我有一个很大的代码改变(叹气).此问题仅出现在类型代理中吗?
示例代码:
private ServiceClient proxy;
using(proxy = new ServiceClient("ConfigName", "http://serviceaddress//service.svc")){
string result = proxy.Method();
}
Run Code Online (Sandbox Code Playgroud) 我正在消耗一个笨重的WCF服务器,偶尔会抛出各种异常,并且还会返回一些错误string.我根本无法访问服务器代码.
我想覆盖内部WCF客户端请求调用方法并处理服务器返回的所有内部异常和硬编码错误,并在Fault发生错误时引发事件,伪:
class MyClient : MyServiceSoapClient
{
protected override OnInvoke()
{
object result;
try
{
result = base.OnInvoke();
if(result == "Error")
{
//raise fault event
}
catch
{
//raise fault event
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,当我打电话时myClient.GetHelloWorld(),它通过我的重写方法.
怎么能实现这一目标?
我知道我不必使用生成的客户端,但我不想再次重新实现所有的合同,我想使用生成的ClientBase子类或至少它的通道.
我需要的是控制内部请求调用方法.
更新
我读了这个答案,看起来它部分是我正在寻找的,但我想知道是否有办法只附加一个IErrorHandler消费者(客户端)代码,我想以ClientBase<TChannel>某种方式将它添加到实例.
更新
这篇文章看起来很有希望,但它不起作用.应用的属性似乎没有生效.我找不到添加IServiceBehavior到客户端的方法.
更新
我试图安装一个IErrorHandler通过IEndpointBehavior.ApplyClientBehavior调用:
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.CallbackDispatchRuntime.ChannelDispatcher.ErrorHandlers
.Add(new ErrorHandler());
}
Run Code Online (Sandbox Code Playgroud)
(clientRuntime是一个参数),但仍会直接跳过异常跳转MyErrorHandler …
在.net core 2.0中使用WCF Web服务引用提供程序向SOAP接口添加连接服务时,System.ServiceModel.ClientBase版本4.2.0.0不再具有4.0.0.0版中的IDisposable接口.
这意味着我不能再将它包装在using语句中(或使用try/finally并处理对象),如下所示:
using (MyClass.MyClassSoapClient client = new MyClass.MyClassSoapClient(EndpointConfiguration.MyClassSoap))
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚为什么IDisposable被删除以及我是否应该尝试自己实现它,或者我是否打算在.net核心中以不同的方式使用SOAP接口?
我正在对在某个时刻挂起的WCF服务进行故障排除.服务行为如下:
[ServiceBehavior( InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple )]
Run Code Online (Sandbox Code Playgroud)
限制参数是:
<serviceThrottling maxConcurrentCalls="50" maxConcurrentSessions="50" maxConcurrentInstances="50" />
Run Code Online (Sandbox Code Playgroud)
以下是从挂起转储中获取的服务状态:
0:000> !mdt 0000000000c9f270 -r
0000000000c9f270 (System.ServiceModel.Dispatcher.ServiceThrottle)
calls:0000000000c9f3d8 (System.ServiceModel.Dispatcher.FlowThrottle)
capacity:0x32 (System.Int32)
count:0x32 (System.Int32)
mutex:0000000000c9f418 (System.Object)
<NO FIELDS>
release:0000000000c9f398 (System.Threading.WaitCallback)
_target:0000000000c9f270 (System.ServiceModel.Dispatcher.ServiceThrottle)
<RECURSIVE>
_methodBase:NULL (System.Reflection.MethodBase)
_methodPtr:0000064273dddf30 (System.IntPtr)
_methodPtrAux:0000000000000000 (System.IntPtr)
_invocationList:NULL (System.Object)
_invocationCount:0000000000000000 (System.IntPtr)
<NO FIELDS>
waiters:0000000000c9f430 (System.Collections.Generic.Queue`1[[System.Object, mscorlib]])
_array:0000000028d73e70 (System.Object[], Elements: 16)
_head:0x1 (System.Int32)
_tail:0xA (System.Int32)
_size:0x9 (System.Int32)
_version:0x22 (System.Int32)
_syncRoot:NULL (System.Object)
propertyName:0000000000c9f2b8 (System.String: "MaxConcurrentCalls")
configName:0000000000c9f358 (System.String: "maxConcurrentCalls")
sessions:0000000000c9f508 (System.ServiceModel.Dispatcher.FlowThrottle)
capacity:0x32 (System.Int32)
count:0x9 (System.Int32)
....
instanceContexts:000000000105ffc8 …Run Code Online (Sandbox Code Playgroud) 当您在ASP.Net框架中创建和使用Web服务代理类时,该类最终继承自实现IDisposable的Component.
我从未在网上看到一个人们处理Web代理类的例子,但是想知道它是否真的需要完成.当我只调用一个方法时,我通常将它包装在using语句中,但如果我需要在整个页面中多次调用它,我可能最终会使用相同的实例,并且只是想知道没有处理的后果是什么它.
我在WCF服务中遇到了一个非常奇怪的错误,当我使用NetTcpBinding时,它似乎以某种方式在套接字级别创建了死锁或线程饥饿.我有一个非常简单的自托管服务:
class Program
{
static void Main(string[] args)
{
using (ServiceHost serviceHost = new ServiceHost(typeof(TestService)))
{
serviceHost.Open();
Console.WriteLine("Press <ENTER> to terminate service.");
Console.ReadLine();
serviceHost.Close();
}
Uri baseAddress = new Uri("net.tcp://localhost:8014/TestService.svc");
}
}
[ServiceContract]
public interface ITestService
{
[OperationContract]
string GetData(string data);
}
public class TestService: ITestService
{
public string GetData(string data)
{
Console.WriteLine(data);
Thread.Sleep(5000);
return "Ok";
}
}
Run Code Online (Sandbox Code Playgroud)
配置部分:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBinding" closeTimeout="00:02:00" openTimeout="00:02:00"
receiveTimeout="00:02:00" sendTimeout="00:02:00" maxBufferSize="2000000000"
maxReceivedMessageSize="2000000000" />
</basicHttpBinding>
<netTcpBinding>
<binding name="netTcpBinding" closeTimeout="00:02:00" openTimeout="00:02:00"
receiveTimeout="00:02:00" sendTimeout="00:02:00" listenBacklog="2000" …Run Code Online (Sandbox Code Playgroud) 关于关闭WCF连接的StackOverflow有几个问题,但排名最高的答案是指这个博客:
http://marcgravell.blogspot.com/2008/11/dontdontuse-using.html
当我在服务器上设置断点并让客户端挂起超过一分钟时,我遇到了这种技术的问题.(我故意创建超时异常)
问题是客户端似乎"挂起",直到服务器完成处理.我的猜测是,一切都在异常后被清理干净.
在考虑到TimeOutException它看来,retry()客户端的逻辑将继续一遍一遍重新提交查询到服务器,在那里我可以看到服务器端的调试器排队的请求,然后执行每一个排队的请求同时被.我的代码不希望WCF这样做,可能是我看到的数据损坏问题的原因.
有些东西并没有完全加入这个解决方案.
什么是在WCF代理中处理故障和异常的无所不包的现代方法?
我已经阅读了几篇关于using语句的文章,试图了解何时应该使用它.这听起来像大多数人认为它应该尽可能多地使用,因为它可以保证处理未使用的物体.
问题是所有的例子总是显示如下:
using (SqlCommand scmFetch = new SqlCommand())
{
// code
}
Run Code Online (Sandbox Code Playgroud)
这是有道理的,但它只是一小段代码.在数据库上执行查询时应该怎么做?所有步骤是什么?它看起来像这样:
string sQuery = @"
SELECT [ID], [Description]
FROM [Zones]
ORDER BY [Description] ";
DataTable dtZones = new DataTable("Zones");
using (SqlConnection scnFetchZones = new SqlConnection())
{
scnFetchZones.ConnectionString = __sConnectionString;
scnFetchZones.Open();
using (SqlCommand scmdFetchZones = new SqlCommand())
{
scmdFetchZones.Connection = scnFetchZones;
scmdFetchZones.CommandText = sQuery;
using (SqlDataAdapter sdaFetch = new SqlDataAdapter())
{
sdaFetch.SelectCommand = scmdFetchZones;
sdaFetch.Fill(dtZones);
}
}
if (scnFetchZones.State == ConnectionState.Open)
scnFetchZones.Close();
}
Run Code Online (Sandbox Code Playgroud)
我想知道的是:
•是否可以使用4,5,10个嵌套的using语句来确保处理所有对象?
•我在什么时候做错了什么,我应该考虑修改吗?
•如果由于嵌套的using语句太多而需要修订,我有哪些选择? …
同步使用后处理/清理Web服务代理实例的最佳做法是什么?
如何如果代理类是源自于不同的答案SoapHttpClientProtocol对ClientBase<T>?
背景
我试图找出为什么我的一个WCF Web服务有时似乎进入一个不再响应服务调用的状态.基本上它似乎挂了,现在我真的没有任何硬数据来弄清楚发生这种情况时会发生什么.
我怀疑可能存在的一个问题是,这个WCF服务本身正在对其他一些服务进行Web服务调用.使用从SoapHttpClientProtocol(使用wsdl.exe制作)派生的代理调用(同步)这些其他服务,此时这些代理实例将由终结器清理:
...
var testProxy = new TestServiceProxy();
var repsonse = testProxy.CallTest("foo");
// process the reponse
...
Run Code Online (Sandbox Code Playgroud)
那么我应该简单地将它们包裹起来using(...) { ... }吗?
...
using(var testProxy = new TestServiceProxy())
{
var repsonse = testProxy.CallTest("foo");
// process the reponse
}
...
Run Code Online (Sandbox Code Playgroud)
如果我要ClientBase<T>通过使用重新创建它们来更改这些代理类,该svcutil.exe怎么办?根据我到目前为止的研究,似乎Dipose()派生类的方法ClientBase<T>将在内部调用Close()类的方法,而这个方法可能反过来抛出异常.因此,基于ClientBase<T>a 包装代理Using()并不总是安全的.
所以重申一个问题:
SoapHttpClientProtocol?ClientBase<T>?我很难过.也许有人可以对我观察到的WCF客户端行为有所了解.
使用WCF示例,我开始使用不同的WCF客户端/服务器通信方法.在并行执行1M测试请求时,我使用SysInternals TcpView来监视开放端口.现在,至少有4种不同的方式来调用客户端:
现在,据我所知,只有选项2-4,显式调用client.Close().在执行期间,我看到许多端口处于TIME_WAIT状态.由于依赖GC,我期望选项1成为最糟糕的情况.然而,令我惊讶的是,它似乎是最干净的,这意味着,它不会留下任何挥之不去的端口.
我错过了什么?
更新:源代码
private static void RunClientWorse(ConcurrentBag<double> cb)
{
var client = new CalculatorClient();
client.Endpoint.Address = new EndpointAddress("net.tcp://localhost:8000/ServiceModelSamples/service");
RunClientCommon(cb, client);
}
private static void RunClientBetter(ConcurrentBag<double> cb)
{
using (var client = new CalculatorClient())
{
client.Endpoint.Address = new EndpointAddress("net.tcp://localhost:8000/ServiceModelSamples/service");
RunClientCommon(cb, client);
}
}
private static void RunClientBest(ConcurrentBag<double> cb)
{
const string Uri = "net.tcp://localhost:8000/ServiceModelSamples/service";
var address = new EndpointAddress(Uri);
//var binding = new NetTcpBinding("netTcpBinding_ICalculator");
using (var factory = new ChannelFactory<ICalculator>("netTcpBinding_ICalculator",address))
{ …Run Code Online (Sandbox Code Playgroud) c# ×8
wcf ×6
asp.net ×2
.net ×1
asp.net-core ×1
exception ×1
net.tcp ×1
performance ×1
proxy ×1
sockets ×1
wcf-client ×1
web-services ×1