Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用C语言在WCF中同时访问PerSession服务#_C#_Wcf_Session_Wcf Binding_Wcf Client - Fatal编程技术网

C# 使用C语言在WCF中同时访问PerSession服务#

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

1.)我有一个主处理方法,它将字符串作为参数,该字符串包含x个任务

2.)我有另一个方法状态,它通过使用两个变量TotalTests和CurrentTest跟踪第一个方法。每次使用第一种方法(处理)中的循环中都会修改它

3)当多个客户端通过传递字符串与我的web服务并行调用处理方法时,具有不同任务的处理时间将更长。因此,与此同时,客户端将使用第二个线程调用Web服务中的Status方法来获取第一个方法的状态

4.)在完成第3点时,所有客户端都应该并行地获取变量(TotalTests、CurrentTest),而不会将out与其他客户端请求混淆

5.)我在下面提供的代码将所有客户机的变量结果混合在一起,当我将它们设置为静态时。如果我删除了变量的static,那么客户端只会得到这两个变量的所有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);
    }
}
[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;

而(i
PerSession
不会使静态变量不在对象实例之间共享。
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++;
    }
}