【发布时间】:2015-09-26 02:42:20
【问题描述】:
我使用了以下代码:
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 只返回了一次,对网关的调用创建了一个套接字客户端,然后接收数据,但它只发生在 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 个?
【问题讨论】:
-
不知道
CallGateway做了什么,很难说... -
好的,我先在其中添加一些登录信息...(另外,请在您发布的代码中多加注意 - 缩进无处不在,而您'已经将所有无用的部分全部注释掉了 - 基本上只是噪音。)理想情况下,提出一个简短但完整的示例来展示正在发生的事情。
-
更多地研究
Task.WaitAll(tasks)和Task.WhenAll(tasks) -
启动所有这些任务后,您的 EXE 会做什么?它是等你停止它还是它只是退出?使用
Parallel.ForEach可能比自己启动任务更好。 -
您使用什么版本的 C#(Visual Studio 版本)进行编译?
foreach和 lambda 的行为在 C#5 (VS 2013) 和更新版本中发生了变化。如果您使用的是旧版本,由于变量捕获的工作原理,您可能会在 4 次内传递相同的变量。
标签: c# multithreading task-parallel-library