我创建了一个 WCF 服务器和一个 WCF 客户端来使用该服务。服务器的目的是将传入的 2 个数字相加,并在返回总和之前等待 X 毫秒。
客户端创建 Y 个任务并启动它们。每个任务都是服务器添加数字并等待 X 毫秒的请求。
当 x = 0 和 y = 1000 时,完成所有任务平均需要 6.2 秒。当 X = 0 和 Y = 10000 时,完成所有任务平均需要 61 秒。
为什么它这么慢,或者这可能是正常的?
谢谢达摩
客户端 C# 方法
private void radButtonTaskWithStatus_Click(object sender, EventArgs e)
{
try
{
var dateTime1 = DateTime.UtcNow;
radProgressBarStatus.Maximum = int.Parse(radTextBoxFloodRequests.Text);
radProgressBarStatus.Value1 = 0;
Random rnd = new Random();
Task<int>[] tasks = new Task<int>[int.Parse(radTextBoxFloodRequests.Text)];
for (int i = 0; i < int.Parse(radTextBoxFloodRequests.Text); i++)
{
int x = i;
tasks[i] = new Task<int>(() =>
{
int FirstRandomNumber = rnd.Next(1, 20);
int SecondRandomNumber = rnd.Next(1, 20);
int result = TaskRequestWithResult(FirstRandomNumber, SecondRandomNumber, int.Parse(radTextBoxFloodDelay.Text), x);
return result;
});
}
var continuation = Task.Factory.ContinueWhenAll(
tasks,
(antecedents) =>
{
var dateTime2 = DateTime.UtcNow;
var diffInSeconds = (dateTime2 - dateTime1).TotalSeconds;
this.radListView1.BeginInvoke((MethodInvoker)(() => this.radListView1.Items.Add((dateTime2 - dateTime1).TotalSeconds)));
//MessageBox.Show(diffInSeconds.ToString());
int total = 0;
for (int i = 0; i < int.Parse(radTextBoxFloodRequests.Text); i++)
total = total + tasks[i].Result;
Debug.Print("Finished - Sum of all results is: " + total);
//RadMessageBox.Show("Finished - Sum of all results is: " + total);
});
for (int i = 0; i < int.Parse(radTextBoxFloodRequests.Text); i++)
{
tasks[i].Start();
// System.Threading.Thread.Sleep(10); // Wait
}
TaskProgress(tasks, count => Invoke(new MethodInvoker(() => radProgressBarStatus.Value1 = count)));
// Use next line if you want to block the main thread until all the tasks are complete
//continuation.Wait();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
public static void TaskProgress(IEnumerable<Task> tasks, Action<int> callback)
{
int count = 0;
foreach (var task in tasks)
task.ContinueWith(t => callback(Interlocked.Increment(ref count)));
}
private int TaskRequestWithResult(int number1, int number2, int delay, int count)
{
try
{
ServiceReference1.WCFJobsLibraryClient Client = new ServiceReference1.WCFJobsLibraryClient();
Client.Endpoint.Address = new System.ServiceModel.EndpointAddress(radTextBoxbaseAddress.Text);
WCFClient.ServiceReference1.ReturnClass AddNumbers_Result;
AddNumbers_Result = Client.AddNumbers(number1, number2, delay);
if (AddNumbers_Result.ErrorCode < 0)
{
// If exception happens, it will be returned here
MessageBox.Show(AddNumbers_Result.ErrorCode.ToString() + " " + AddNumbers_Result.ErrorMessage + " " + AddNumbers_Result.ExMessage);
}
else
{
Debug.Print("Task Executing now: " + count.ToString());
}
return AddNumbers_Result.Result;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
return -1;
}
}
}
客户端 App.config
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8732/Design_Time_Addresses/WCFService/WCFJobsLibrary/"
binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpoint"
contract="ServiceReference1.IWCFJobsLibrary" name="BasicHttpEndpoint" />
</client>
</system.serviceModel>
</configuration>
服务器 C# 方法
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class WCFJobsLibrary : IWCFJobsLibrary
{
public ReturnClass AddNumbers(int FirstNumber, int SecondNumber, int Delay) //Add two numbers and wait a predefined interval
{
Logging.Write_To_Log_File("Entry", MethodBase.GetCurrentMethod().Name, "", "", "", 1);
ReturnClass myReturnClass = new ReturnClass(-1, null, null, 0);
try
{
myReturnClass.ErrorCode = 1;
myReturnClass.Result = FirstNumber + SecondNumber;
System.Threading.Thread.Sleep(Delay); // Wait
Logging.Write_To_Log_File("Exit", MethodBase.GetCurrentMethod().Name, "", "", "", 1);
return myReturnClass;
}
catch (Exception ex)
{
Logging.Write_To_Log_File("Error", MethodBase.GetCurrentMethod().Name, "", "", ex.ToString(), 2);
myReturnClass.ErrorCode = -1;
myReturnClass.ErrorMessage = ex.ToString();
return myReturnClass;
}
}
//Add two numbers and wait defined interval
[OperationContract]
ReturnClass AddNumbers(int FirstNumber, int SecondNumber, int Delay);
服务器应用程序.config
<configuration>
<system.serviceModel>
<services>
<service name="WCFService.WCFJobsLibrary" behaviorConfiguration="Throttled" >
<endpoint address="" binding="basicHttpBinding" bindingConfiguration=""
name="BasicHttpEndpoint" contract="WCFService.IWCFJobsLibrary">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/WCFService/WCFJobsLibrary/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Throttled">
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="100000" maxConcurrentInstances="100000" maxConcurrentSessions="100000" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>