Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.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# 使用回调通道的WCF TimeoutException_C#_.net_Wcf - Fatal编程技术网

C# 使用回调通道的WCF TimeoutException

C# 使用回调通道的WCF TimeoutException,c#,.net,wcf,C#,.net,Wcf,我是WCF的新手,目前正在尝试建立并运行一个业务需求。为了给你一些背景知识,我需要一个windows服务,它可以通过.NET产品与其他进程(进程间通信)进行通信。我们的想法是,在任何时候,我们所有的产品都只能运行一个计时器,中央代理会告诉每个程序根据用户希望运行的计时器启动/停止 目前,我只想让同一个客户机项目运行两次,以启动/停止彼此的计时器,然后再将其扩展到数百个其他项目 我收到的错误如下所示,当第二个客户端连接并调用StartTimer时会发生此错误: An unhandled excep

我是WCF的新手,目前正在尝试建立并运行一个业务需求。为了给你一些背景知识,我需要一个windows服务,它可以通过.NET产品与其他进程(进程间通信)进行通信。我们的想法是,在任何时候,我们所有的产品都只能运行一个计时器,中央代理会告诉每个程序根据用户希望运行的计时器启动/停止

目前,我只想让同一个客户机项目运行两次,以启动/停止彼此的计时器,然后再将其扩展到数百个其他项目

我收到的错误如下所示,当第二个客户端连接并调用StartTimer时会发生此错误:

An unhandled exception of type 'System.TimeoutException' occurred in mscorlib.dll

Additional information: This request operation sent to net.tcp://localhost:9044/TimeRecordingService did not receive a reply within the configured timeout (00:01:00).  The time allotted to this operation may have been a portion of a longer timeout.  This may be because the service is still processing the operation or because the service was unable to send a reply message.  Please consider increasing the operation timeout (by casting the channel/proxy to IContextChannel and setting the OperationTimeout property) and ensure that the service is able to connect to the client.
我最初认为问题与并发连接/允许的最大连接有关。但是,在我的App.Config中设置了以下选项后,我发现问题仍然存在

<connectionManagement>
    <add maxconnection="500" address="*"/>
</connectionManagement>
...
<serviceBehaviors>
    <behavior name="ThrottlingIssue">
    <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" />
    </behavior>
</serviceBehaviors>
服务接口:

[ServiceContract(CallbackContract = typeof(ITimeRecordingClient))]
public interface ITimeRecordingService
{
[OperationContract]
void Login(string Username, string Password);

[OperationContract]
void Listen();

[OperationContract]
void StopListening();

[OperationContract]
void StartTimer(string ID);

[OperationContract]
void AddTimer(string ID);
} 
服务:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)]
public class TimeRecordingServiceImpl : ITimeRecordingService
{
  private ApplicationUser _user;
  private List<ITimeRecordingClient> _lstCons = new List<ITimeRecordingClient>();
  private Dictionary<string, bool> _tmrs = new Dictionary<string, bool>();
  public TimeRecordingServiceImpl()
  {
     System.Net.ServicePointManager.DefaultConnectionLimit = 200;
  }
  public void Login(string Username, string Password)
  {
    var user = new ApplicationUser { Username = Username, Password = Password };
    _user = user;

    foreach (ITimeRecordingClient con in _lstCons)
      con.ReceiveMessage(Username, Password);
  }

  public void AddTimer(string ID)
  {
    _tmrs.Add(ID, false);
  }

  public void StartTimer(string ID)
  {
    List<string> lstIDs = new List<string>(); 
    foreach (KeyValuePair<string, bool> kvp in _tmrs)
    {
      if (kvp.Key != ID)
      {
        foreach (ITimeRecordingClient con in _lstCons)
        {
          try
          {
            con.StopTimer(kvp.Key);
          }
          catch { }

        }
                lstIDs.Add(kvp.Key);
      }
    }

    _tmrs[ID] = true;
    foreach (string strID in lstIDs)
    _tmrs[strID] = false;
  }

  public void Listen()
  {
    var connection = OperationContext.Current.GetCallbackChannel<ITimeRecordingClient>();
    _lstCons.Add(connection);
  }

  public void StopListening()
  {
    var con = OperationContext.Current.GetCallbackChannel<ITimeRecordingClient>();
    _lstCons.Remove(con);
  }
}
回调实现:

Public Class TimeRecordingClientImpl
    Implements ITimeRecordingClient

    Public Event MessageReceived(Username As String, Password As String)
    Public Event RequestStopTimer(ID As String)
    Public Sub ReceiveMessage(Username As String, Password As String) Implements ITimeRecordingClient.ReceiveMessage
        RaiseEvent MessageReceived(Username, Password)
    End Sub

    Public Sub StopTimer(ID As String) Implements ITimeRecordingClient.StopTimer
        RaiseEvent RequestStopTimer(ID)
    End Sub
End Class

我已经对我的问题做了很多调查,发现这是因为我通过所有打开的连接循环,告诉他们停止计时器,包括当前调用我的事件的连接,因此尝试访问回调通道导致了阻塞

在处理请求期间,您无法访问回调通道

我实施了以下代码更改以解决此问题:

之前:

try
{
  con.StopTimer(kvp.Key);
}
catch { }
之后:

try
{
  if (OperationContext.Current.GetCallbackChannel<ITimeRecordingClient>() != con)
  {
    con.StopTimer(kvp.Key);
  }
}
catch { }
试试看
{
if(OperationContext.Current.GetCallbackChannel()!=con)
{
con.停止计时器(kvp.键);
}
}
捕获{}

我对我的问题做了大量调查,发现这是因为我在所有打开的连接中循环,告诉他们停止计时器,包括当前调用我的事件的连接,因此尝试访问回调通道导致了阻塞

在处理请求期间,您无法访问回调通道

我实施了以下代码更改以解决此问题:

之前:

try
{
  con.StopTimer(kvp.Key);
}
catch { }
之后:

try
{
  if (OperationContext.Current.GetCallbackChannel<ITimeRecordingClient>() != con)
  {
    con.StopTimer(kvp.Key);
  }
}
catch { }
试试看
{
if(OperationContext.Current.GetCallbackChannel()!=con)
{
con.停止计时器(kvp.键);
}
}
捕获{}