我在申请中看到了几个问题。以下是重现问题的示例代码。
服务:
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value, int minDelaySeconds, int maxDelaySeconds);
}
[ServiceBehavior(
InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Service1 : IService1
{
/// <summary>
/// Simulates an operation. Generates a random string, and sleeps for sometime to simulate a long running operation.
/// </summary>
/// <param name="value">length of string</param>
/// <param name="min">minimum time delay. units: seconds</param>
/// <param name="max">maximum time delay. units: seconds</param>
/// <returns></returns>
public string GetData(int value, int min, int max)
{
var r = new Random();
var bytes = new byte[value];
r.NextBytes(bytes);
var s = Convert.ToBase64String(bytes);
Thread.Sleep(TimeSpan.FromSeconds(r.NextDouble() * (max - min) + min));
return s;
}
}
服务配置(使用自定义绑定):
<customBinding>
<binding name="myHttpBinding">
<reliableSession />
<binaryMessageEncoding />
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
</binding>
</customBinding>
客户端(并行调用服务):
static void Main(string[] args)
{
using (var tw = Console.Out)
{
try
{
ServicePointManager.DefaultConnectionLimit = 100;
int numberOfthreads, minDelay, maxDelay, minPayLoad, maxPayLoad, numberOfRequests;
ParseCmdArgs(args, out numberOfthreads, out minDelay, out maxDelay, out minPayLoad, out maxPayLoad, out numberOfRequests);
var interceptor = new Interceptor();
var r = new Random();
using (var svc = new ServiceReference1.Service1Client())
{
svc.Endpoint.EndpointBehaviors.Add(interceptor);
var tasks = new Task[numberOfthreads];
int threadId = 0;
for (int ctr = 0; ctr < numberOfthreads; ctr++)
{
tasks[ctr] = Task.Run(async () =>
{
int id = Interlocked.Increment(ref threadId);
var count = 0;
while (count < numberOfRequests)
{
Thread.CurrentThread.Name = id.ToString();
await svc.GetDataAsync(r.Next(minPayLoad, maxPayLoad), minDelay, maxDelay);
// you will be on a different thread now, than the thread which made the call
Debug.Assert(string.IsNullOrEmpty(Thread.CurrentThread.Name)); // note
count++;
}
tw.WriteLine("Thread {0} is exiting...", id);
});
}
Task.WaitAll(tasks);
}
}
catch (Exception e)
{
LogException(e, tw);
}
}
}
客户端配置:
<system.net>
<connectionManagement>
<add address="*" maxconnection="100"/>
</connectionManagement>
</system.net>
...
<customBinding>
<binding name="myHttpBinding">
<reliableSession />
<binaryMessageEncoding />
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
</binding>
</customBinding>
问题:
// cmd行参数说明:并行5个请求,5-30秒之间的时间延迟,消息大小在100kb-1MB之间,每个“线程”在退出前进行5次调用
c:\Users\me\Documents\Visual Studio 2012\Projects\ConsoleApplication8\Test
Client1\bin\Debug>run2 5 5 30 100000 1000000 5
[2] 1 Sending request...Received Response 502,492.00 bytes in 18.8 sec
[3] 2 Sending request...Received Response 313,662.00 bytes in 29.0 sec
[4] 3 Sending request...Received Response 1,236,254.00 bytes in 27.5 sec
[1] 4 Sending request...Received Response 1,250,170.00 bytes in 36.3 sec
[5] 5 Sending request...Received Response 151,803.00 bytes in 54.8 sec
[2] 6 Sending request...Received Response 625,859.00 bytes in 26.8 sec
[4] 7 Sending request...Received Response 395,976.00 bytes in 47.6 sec
[3] 8 Sending request...Received Response 945,664.00 bytes in 45.1 sec
[1] 9 Sending request...Received Response 1,287,904.00 bytes in 73.5 sec
[2] 10 Sending request...Received Response 1,312,428.00 bytes in 52.9 sec
[5] 11 Sending request...Received Response 1,045,727.00 bytes in 103.3 sec
[3] 12 Sending request...Received Response 190,310.00 bytes in 107.5 sec
[4] 13 Sending request...
[2] 14 Sending request...
[1] 15 Sending request...
[5] 16 Sending request...Received Response 1,323,274.00 bytes in 36.4 sec
[3] 17 Sending request...Received Response 1,090,367.00 bytes in 13.4 sec
[5] 18 Sending request...Received Response 458,598.00 bytes in 28.8 sec
[3] 19 Sending request...Received Response 1,185,986.00 bytes in 28.3 sec
[5] 20 Sending request...Received Response 731,178.00 bytes in 27.0 sec
Thread 3 is exiting...
Thread 5 is exiting...
One or more errors occurred.
at System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeou
t)
at System.Threading.Tasks.Task.WaitAll(Task[] tasks)
at TestClient1.Program.Main(String[] args) in c:\Users\me\Documents\Vis
ual Studio 2012\Projects\ConsoleApplication8\TestClient1\Program.cs:line 48
The message could not be transferred within the allotted timeout of 00:01:00. Th
ere was no space available in the reliable channel's transfer window. The time a
llotted to this operation may have been a portion of a longer timeout.
at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncR
esult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[
] outs, IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.<>c__DisplayC
lass5`1.<CreateGenericTask>b__4(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar,
Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchron
ization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at TestClient1.Program.<>c__DisplayClass8.<<Main>b__0>d__a.MoveNext() in c:\U
sers\me\Documents\Visual Studio 2012\Projects\ConsoleApplication8\TestClie
nt1\Program.cs:line 40
答案 0 :(得分:0)
我最初的想法是并发模式没有设置为多个。但是,我认为这毕竟是设定的。你可能会被扼杀。我认为会话默认为10。所以,如果你没有为会话设置节流,这可能是造成它的原因。尝试将ServiceThrottlingBehavior中的maxConncurentSessions提升到更高的数字(例如20)。
1&amp;的解决方案2可能会解决此问题,因为您似乎超出了空闲超时设置。如果你可以打开更多东西,那么我认为这将会消失。
您可能想要更改的是使用构造....在客户端上使用(var svc = new ServiceReference1.Service1Client())。请参阅此文档了解详细信息http://msdn.microsoft.com/en-us/library/aa355056.aspx。在使用WCF代理时,应该使用try / finally结构。