C# 使用C语言在WCF中同时访问PerSession服务#
1.)我有一个主处理方法,它将字符串作为参数,该字符串包含x个任务 2.)我有另一个方法状态,它通过使用两个变量TotalTests和CurrentTest跟踪第一个方法。每次使用第一种方法(处理)中的循环中都会修改它 3)当多个客户端通过传递字符串与我的web服务并行调用处理方法时,具有不同任务的处理时间将更长。因此,与此同时,客户端将使用第二个线程调用Web服务中的Status方法来获取第一个方法的状态 4.)在完成第3点时,所有客户端都应该并行地获取变量(TotalTests、CurrentTest),而不会将out与其他客户端请求混淆 5.)我在下面提供的代码将所有客户机的变量结果混合在一起,当我将它们设置为静态时。如果我删除了变量的static,那么客户端只会得到这两个变量的所有0,我无法修复它。请看下面的代码C# 使用C语言在WCF中同时访问PerSession服务#,c#,wcf,session,wcf-binding,wcf-client,C#,Wcf,Session,Wcf Binding,Wcf Client,1.)我有一个主处理方法,它将字符串作为参数,该字符串包含x个任务 2.)我有另一个方法状态,它通过使用两个变量TotalTests和CurrentTest跟踪第一个方法。每次使用第一种方法(处理)中的循环中都会修改它 3)当多个客户端通过传递字符串与我的web服务并行调用处理方法时,具有不同任务的处理时间将更长。因此,与此同时,客户端将使用第二个线程调用Web服务中的Status方法来获取第一个方法的状态 4.)在完成第3点时,所有客户端都应该并行地获取变量(TotalTests、Curren
[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);
}
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
公共类服务1:IService1
{
公共整数测试=0;
公共int CurrentTest=0;
公共字符串处理(字符串原始XmlString)
{
XmlDocument XmlDoc=新的XmlDocument();
LoadXml(原始XMLString);
this.TotalTests=XmlDoc.GetElementsByTagName(“TestScenario”).Count;//在给定的xml字符串中查找总测试方案的计数
此.CurrentTest=0;
而(iPerSession
不会使静态变量不在对象实例之间共享。PerSession
上下文模式所做的唯一事情就是控制对象的生存期
使用PerSession
WCF在会话结束之前不会销毁服务对象。会话可以由客户端显式关闭或超时关闭(默认值为10分钟)。具有相同会话Id的客户端的下一次调用都将由WCF路由到现有对象
变量不应是静态的,以防止在不同的服务实例之间共享。只要您使用维护会话的InstanceContextMode.PerSession
和绑定,变量的状态将由WCF维护
public int TotalTests = 0;
public int CurrentTest = 0;
我还想在合同中添加SessionMode.Required
,以确保服务配置正确
[ServiceContract(SessionMode = SessionMode.Required )]
首先,因为您需要同时访问服务,所以当服务处理第一个客户端调用(处理)时,您需要将服务并发模式更改为多个
您还希望维护每个客户端的处理状态,因此需要将实例上下文模式设置为PerSession
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode= InstanceContextMode.PerSession)]
注意
- 默认InstanceContextMode为PerSession
- 默认并发模式为单
您可以执行以下操作以确保您的配置与PerSession InstanceContextMode兼容,使用此方法,WCF将在必要时引发运行时异常
[ServiceContract(SessionMode=SessionMode.Required)]
注意使用InstanceContextMode.PerSession,您将为创建的每个代理获得不同的实例
因此,每个客户机只需要一个“Service1Client”实例,您将调用其流程方法并从中检索状态
另外,对于虚拟重处理,您可以仅在“处理”方法(服务端)中使用Thread.Sleep(毫秒)进行测试
对于客户端应用程序,如果要调用“Processing”方法,然后使用Status方法检索状态,则需要异步调用Process方法
1.右键单击解决方案资源管理器中的服务引用,选择“配置服务引用”,然后选中“生成异步操作”,然后按“确定”
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++;
}
}
正如您所说,我也很累,但这次变量值显示为0。@Beygi----我已按照您的建议进行了修改。请查看一下。您确定绑定已启用会话吗?如果未启用,请同时提供客户端和服务器配置。两个调用是否都在一个会话中?-请提供客户端代码。@DmitryHarnitski---提供了您请求的完整附加信息。请查看每个新客户端都使用新的sesson,以便在会话1和状态()中运行Processing()在session2中运行。创建一个客户端对象并将其用于两个客户端对象methods@DmitryHarnitski----客户端是相同的,只有一个客户端会调用这两个方法。@Beygi----如果我每个客户端只执行一个Service1Client实例,那么我无法使线程并行工作。要检查我是否得到正确的输出。@krishna555“更新已成功完成”。:)我是否需要在服务器上进行任何代码更改(wcf服务)您上面提供的客户机代码并不是并行执行的,因为它首先调用处理,然后等待处理完成,然后给出Status方法的最终结果。@krishna555不要忘记您需要执行我在回答中提供的所有步骤,而不是j自定义客户端代码。
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode= InstanceContextMode.PerSession)]
[ServiceContract(SessionMode=SessionMode.Required)]
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++;
}
}