2015-09-25 68 views
0

我用下面的代码:Task.StartNew()多次调用返回只有一次

var tuple = Tuple.Create("xxx.xx.xx.xxx", 6102, "109", "Metrix1", 1); 
var tuple1 = Tuple.Create("xxx.xx.xx.xxx", 6102, "110", "Metrix2", 1); 
var tuple2 = Tuple.Create("xxx.xx.xx.xxx", 6102, "111", "Metrix3", 1); 
var tuple3 = Tuple.Create("xxx.xx.xx.xxx", 6103, "106", "Metrix4", 2); 

gateways.Add(tuple); 
gateways.Add(tuple1); 
gateways.Add(tuple2); 
gateways.Add(tuple3); 

foreach (var gatewayId in gateways) 
{ 
    Task.Factory.StartNew(
     () => GetJobs(
      gatewayId.Item1, 
      gatewayId.Item2, 
      gatewayId.Item3, 
      gatewayId.Item4, 
      gatewayId.Item5)); 
} 

这然后调用GetJobs这就要求CallGateway,如果需要ProcessMessageNew

private string GetJobs(string Url , int portNumber, string Engineer , string mEngineer , int GatewayId) 
{ 
    ConfigLogger.Instance.LogInfo("info", "Calling Gateway Start: " + DateTime.Now.ToString("HH:mm:ss.ffff") + " for engineer: " + Engineer); 
    string gatewayResult = CallGateway(Engineer, Url, portNumber); 
    ConfigLogger.Instance.LogInfo("info", "Calling Gateway End: " + DateTime.Now.ToString("HH:mm:ss.ffff") + " for engineer: " + Engineer); 
    if (gatewayResult != null) 
    { 
     ConfigLogger.Instance.LogInfo("info", "Processing Request Message: " + DateTime.Now.ToString("HH:mm:ss.ffff") + " for engineer: " + Engineer); 
     ProcessMessageNew(gatewayResult, Engineer, Url, portNumber , MEngineer ,PGatewayId); 
    } 
    return gatewayResult; 
} 

CallGateway

public string CallGateway(string gatewayUrl, int portNumber , string engineer) 
{ 
    string result = null; 
    int streamBufferSize = 1000; 

    IPHostEntry ipHostInfo = Dns.Resolve(gatewayUrl.ToString()); 
    IPAddress ipAddress = ipHostInfo.AddressList[0]; 
    IPEndPoint remoteEP = new IPEndPoint(ipAddress, portNumber); 

    // Create a TCP/IP socket. 
    Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    clientSocket.Connect(ipAddress, portNumber); 

    // Set these on app param 
    clientSocket.ReceiveTimeout = 300000; 
    clientSocket.SendTimeout = 60000; 
    // build message string to send to gateway 
    string message = BuildMessageGetJobsFromGateway(engineer, SendTypeIn); 

    // Create a NetworkStream that owns clientSocket and 
    // then create a BufferedStream on top of the NetworkStream. 
    // Both streams are disposed when execution exits the 
    // using statement. 
    using (var netStream = new NetworkStream(clientSocket, true), 
      var bufStream = new BufferedStream(netStream, streamBufferSize)) 
    { 
      // Check whether the underlying stream supports seeking. 
      Console.WriteLine("NetworkStream {0} seeking.\n", bufStream.CanSeek ? "supports" : "does not support"); 

      //variable used to only close once 
      bool doClose = true; 

      // Send and receive data. 
      if (bufStream.CanWrite) 
      { 
       try 
       { 
        SendData(netStream, bufStream, SendTypeIn, message); 
       } 
       catch (Exception exSend) 
       { 
        Console.WriteLine(exSend.Message.ToString()); 
       } 
      } 
      if (bufStream.CanRead) 
      { 
       try 
       { 
        result = ReceiveData(netStream, bufStream, clientSocket); 
       } 
       catch (Exception exRecieve) 
       { 
        // 
       } 
       finally 
       { 
        Console.WriteLine("Closing Stream"); 
        doClose = false; 
        bufStream.Close(); 
        clientSocket.Close(); 
       } 
      } 

      // When bufStream is closed, netStream is in turn 
      // closed, which in turn shuts down the connection 
      // and closes clientSocket. 
      Console.WriteLine("\nShutting down the connection."); 

      // only close if no exception is raised 
      if (doClose) 
      { 
       bufStream.Close(); 
       clientSocket.Close(); 
      } 
     } 
     return result; 
    } 
} 

但是,我在日志文件4来电去电网关方法和工程师106只有一个返回,调用网关创建一个Socket客户端,然后接收数据,但只发生了一出4个电话:

[MobileGateway.exe] - [Info] - [25/09/2015 16:47:19] - Calling Gateway Start: 16:47:19.6574 for engineer: 109 
[MobileGateway.exe] - [Info] - [25/09/2015 16:47:19] - Processing Call Mobile Gateway: 16:47:19.6624 
[MobileGateway.exe] - [Info] - [25/09/2015 16:47:20] - Calling Gateway Start: 16:47:20.6685 for engineer: 110 
[MobileGateway.exe] - [Info] - [25/09/2015 16:47:20] - Processing Call Mobile Gateway: 16:47:20.6875 
[MobileGateway.exe] - [Info] - [25/09/2015 16:47:21] - Calling Gateway Start: 16:47:21.6696 for engineer: 111 
[MobileGateway.exe] - [Info] - [25/09/2015 16:47:21] - Processing Call Mobile Gateway: 16:47:21.6716 
[MobileGateway.exe] - [Info] - [25/09/2015 16:47:22] - Calling Gateway Start: 16:47:22.6686 for engineer: 106 
[MobileGateway.exe] - [Info] - [25/09/2015 16:47:22] - Processing Call Mobile Gateway: 16:47:22.6706 
[MobileGateway.exe] - [Info] - [25/09/2015 16:47:23] - Processing Call Mobile Ended: 16:47:23.0476 
[MobileGateway.exe] - [Info] - [25/09/2015 16:47:23] - Calling Gateway End: 16:47:23.0486 for engineer: 106 
[MobileGateway.exe] - [Info] - [25/09/2015 16:47:23] - Processing Request Message: 16:47:23.0486 for engineer: 106 
[MobileGateway.exe] - [Info] - [25/09/2015 16:47:23] - Message Recieved From Gateway: 16:47:23.0496 

的调用应该是并行或异步处理,因为需要同时调用此方法超过1000次,并且它们是长时间运行的进程,所以我需要一次处理多个进程。

任何想法,为什么我得到1响应而不是4?

+0

不知道什么'CallGateway'做的,这是很难说... –

+0

添加呼叫网关。 – user3262640

+0

好吧,我开始在那里添加一些日志记录......(另外,请多注意一下你发布的代码 - 缩进遍布整个地方,并且你已经完成了注释部分那什么都不做 - 所以基本上只是噪音。)理想情况下,想出一个*简短的*但是完整的例子来展示正在发生的事情。 –

回答

0

由于您对代码中的地址进行了xxx处理,所以我不能肯定地说,但这可能是因为您以前的三个网关拥有相同的端口号6102。因此,您正在平行地关闭并打开三次同一地址的流,并且抛出异常,以便稍后默默捕获。

此外,你可以通过在单件网关对象,如下面的提高代码的可读性和可维护性:

foreach (var gatewayId in gateways) 
{ 
    Task.Factory.StartNew(() => GetJobs(gatewayId)); 
} 

太修改GetJobs方法:

private string GetJobs(Gateway gateway) 
{ 
    ConfigLogger.Instance.LogInfo("info", "Calling Gateway Start: " + DateTime.Now.ToString("HH:mm:ss.ffff") + " for engineer: " + gateway.Engineer); 
    string gatewayResult = CallGateway(gateway); 
    ConfigLogger.Instance.LogInfo("info", "Calling Gateway End: " + DateTime.Now.ToString("HH:mm:ss.ffff") + " for engineer: " + gateway.Engineer); 
    if (gatewayResult != null) 
    { 
     ConfigLogger.Instance.LogInfo("info", "Processing Request Message: " + DateTime.Now.ToString("HH:mm:ss.ffff") + " for engineer: " + gateway.Engineer); 
     ProcessMessageNew(gatewayResult, gateway); 
    } 
    return gatewayResult; 
} 

而且,进一步下降,请更改您的ProcessMessageNewCallGateway,以符合上述代码中的新定义。

+0

我认为这是正确的。因此,所有调用相同IP和端口的Socket应该在一个连接中完成? – user3262640

+0

@ user3262640:可能只需为每个CallGateway提供不同的端口号就可以为你工作,看到新的端口号不会与你机器上的其他应用程序发生冲突 – displayName

+0

我无法提供不同的端口号,因为我需要拨打3个呼叫到相同的IP和portNumber与不同的变量。IP和端口号是我打电话给的服务器,我的机器是客户端 – user3262640