1。)我有一个主方法Processing,它将字符串作为参数,该字符串包含一些x个任务。
2。)我有另一种方法Status,它通过使用两个变量TotalTests和CurrentTest来跟踪第一个方法。每次在第一种方法(处理)中循环修改。
3.。)当多个客户端与我的Web服务并行调用以通过传递字符串来调用Processing方法时,具有不同任务的字符串将花费更多时间来处理。所以,客户端将使用第二个线程调用webservice中的Status方法来获取第一个方法的状态。
4。)当第3点进行时,所有客户端都应该并行获取变量(TotalTests,CurrentTest),而不是与其他客户端请求混淆。
5.)我在下面提供的代码是当我将它们设置为静态时,为所有客户端获取混合变量结果。如果我为变量删除静态,那么客户端只是得到这两个变量的全0,我无法修复它。请看下面的代码。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class Service1 : IService1
{
public int TotalTests = 0;
public int CurrentTest = 0;
public string Processing(string OriginalXmlString)
{
XmlDocument XmlDoc = new XmlDocument();
XmlDoc.LoadXml(OriginalXmlString);
this.TotalTests = XmlDoc.GetElementsByTagName("TestScenario").Count; //finding the count of total test scenarios in the given xml string
this.CurrentTest = 0;
while(i<10)
{
++this.CurrentTest;
i++;
}
}
public string Status()
{
return (this.TotalTests + ";" + this.CurrentTest);
}
}
服务器配置
<wsHttpBinding>
<binding name="WSHttpBinding_IService1" closeTimeout="00:10:00"
openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="true" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
客户端配置
<wsHttpBinding>
<binding name="WSHttpBinding_IService1" closeTimeout="00:10:00"
openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="true" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
下面提到的是我的客户代码
class Program
{
static void Main(string[] args)
{
Program prog = new Program();
Thread JavaClientCallThread = new Thread(new ThreadStart(prog.ClientCallThreadRun));
Thread JavaStatusCallThread = new Thread(new ThreadStart(prog.StatusCallThreadRun));
JavaClientCallThread.Start();
JavaStatusCallThread.Start();
}
public void ClientCallThreadRun()
{
XmlDocument doc = new XmlDocument();
doc.Load(@"D:\t72CalculateReasonableWithdrawal_Input.xml");
bool error = false;
Service1Client Client = new Service1Client();
string temp = Client.Processing(doc.OuterXml, ref error);
}
public void StatusCallThreadRun()
{
int i = 0;
Service1Client Client = new Service1Client();
string temp;
while (i < 10)
{
temp = Client.Status();
Thread.Sleep(1500);
Console.WriteLine("TotalTestScenarios;CurrentTestCase = {0}", temp);
i++;
}
}
}
任何人都可以帮忙。
答案 0 :(得分:1)
首先,因为您需要同时访问服务,当服务正在处理第一个客户端调用(处理)时,您需要将服务并发模式更改为多个。
您还希望维护每个客户端处理状态,因此您需要将实例上下文模式设置为PerSession。
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode= InstanceContextMode.PerSession)]
注意强>
- 默认InstanceContextMode是PerSession
- 默认ConcurrencyMode为Single
您可以执行以下操作以确保您的配置与PerSession InstanceContextMode兼容,使用此方法,WCF将在必要时抛出运行时异常
[ServiceContract(SessionMode=SessionMode.Required)]
注意使用InstanceContextMode.PerSession,您将为每个创建的代理获取不同的实例
因此,每个客户端只需要一个“Service1Client”实例,您将调用其Process方法并从中检索状态。
对于虚拟重处理,您只能在“处理”方法(服务端)中使用Thread.Sleep(毫秒)进行测试。
对于客户端应用程序,如果要调用“Processing”方法,然后使用Status方法检索状态,则需要异步调用Process方法。
1.右键单击solution-explorer中的服务引用,选择“Configure Service Reference”,然后选中“Generate asynchronous operation”并按“OK”。
2.更改您的客户端代码
static void Main(string[] args)
{
StartProcessing();
StatusReport();
Console.ReadLine();
}
static ServiceClient Client = new ServiceClient();
private static bool Completed = false;
public static void StartProcessing()
{
XmlDocument doc = new XmlDocument();
doc.Load(@"D:\t72CalculateReasonableWithdrawal_Input.xml");
bool error = false;
Client.ProcessingCompleted += Client_ProcessingCompleted;
Client.ProcessingAsync(doc.OuterXml);
Console.WriteLine("Processing...");
}
static void Client_ProcessingCompleted(object sender, ProcessingCompletedEventArgs e)
{
// processing is completed, retreive the return value of Processing operation
Completed = true;
Console.WriteLine(e.Result);
}
public static void StatusReport()
{
int i = 0;
string temp;
while (!Completed)
{
temp = Client.Status();
Console.WriteLine("TotalTestScenarios;CurrentTestCase = {0}", temp);
Thread.Sleep(500);
i++;
}
}
答案 1 :(得分:0)
PerSession
不会使您的静态变量不在对象实例之间共享。 PerSession
上下文模式唯一能做的就是控制对象的生命周期。
使用PerSession
WCF在会话结束之前不会销毁服务对象。会话可以由客户端或超时明确关闭(默认为10分钟)。来自具有相同会话ID的客户端的每个下一个呼叫将由WCF路由到现有对象。
变量不应该是静态的,以防止跨不同服务实例共享。只要您使用InstanceContextMode.PerSession
和维护会话的绑定,WCF就会维护变量状态。
public int TotalTests = 0;
public int CurrentTest = 0;
我还会将SessionMode.Required
添加到合同中,以确保正确配置服务。
[ServiceContract(SessionMode = SessionMode.Required )]