在我的 Web Api 应用程序中,我试图调用其他我的 api 应用程序。应用程序在本地托管。调用是同步的,整个链看起来像这样:
客户端 -[req]-> EchoService -[req]-> EchoService2 -[resp]-> EchoService -[resp]-> 客户端
从字面上看,这些只是回显命令。问题:当有 3 个或更多客户端并行调用第一个服务时,对第二个服务的调用会挂起。
这是代码:
回声服务2:
public class Echo2Controller : ApiController
{
[Route("Echo/{Message}/{RequestID}/{SessionToken}")]
public IHttpActionResult GetEcho(string Message, string RequestID, string SessionToken)
{
EchoResponse response = new EchoResponse();
response.Payload.Message = "Echo 2: " + Message;
response.Success = true;
return Ok(response);
}
}
回声服务:
public class EchoController : ApiController
{
[Route("Echo/{Message}/{RequestID}/{SessionToken}")]
public IHttpActionResult GetEcho(string Message, string RequestID, string SessionToken)
{
EchoResponse response = new EchoResponse();
try
{
string echo2Resp = string.Empty;
using (var client = new WebClient())
{
**// STUCKS HERE WHEN 3 OR MORE CLIENTS**
string sResp = client.DownloadString("http://localhost/api/echoservice2/Echo/" + Message + "/2/3");
EchoResponse echoResponse = JsonConvert.DeserializeObject<EchoResponse>(sResp);
echo2Resp = echoResponse.Payload.Message;
}
response.Payload.Message = "Echo: " + echo2Resp;
response.Success = true;
}
catch(Exception ex)
{
response.Payload.Message = "Echo: Error!";
response.Errors.Add(new Error() { Code = EErrorCodes.GeneralError, Type = EErrorType.Error, Message = ex.Message });
response.Success = false;
}
return Ok(response);
}
}
客户端(控制台应用程序):
{
public int Timeout { get; set; }
protected override WebRequest GetWebRequest(Uri uri)
{
WebRequest lWebRequest = base.GetWebRequest(uri);
lWebRequest.Timeout = Timeout;
((HttpWebRequest)lWebRequest).ReadWriteTimeout = Timeout;
return lWebRequest;
}
}
class Program
{
static void Main(string[] args)
{
int tasksCount = 2; // WHEN 2 - works ok, WHEN 3 or more - hangs!**
List<Task> importTasks = new List<Task>();
for(int i = 0; i < tasksCount; ++i)
{
Task importTask = new Task(() => ThreadEcho());
importTasks.Add(importTask);
importTask.Start();
}
Task.WaitAll(importTasks.ToArray());
}
private static void ThreadEcho()
{
int count = 10;
var rnd = new Random(DateTime.Now.Millisecond);
while (count > 0)
{
try
{
string message = Guid.NewGuid().ToString();
string echoResp = string.Empty;
using (var client = new MyWebClient())
{
client.Timeout = 300000;
string sResp = client.DownloadString("http://localhost/api/echoservice/Echo/" + message + "/2/3");
EchoResponse echoResponse = JsonConvert.DeserializeObject<EchoResponse>(sResp);
echoResp = echoResponse.Payload.Message;
}
Console.WriteLine(string.Format("[{0}] [{1}] Request completed: {2} ",
DateTime.Now,
System.Threading.Thread.CurrentThread.ManagedThreadId,
echoResp));
}
catch(Exception ex)
{
Console.WriteLine(string.Format("[{0}] [{1}] Error: {2} ",
DateTime.Now,
System.Threading.Thread.CurrentThread.ManagedThreadId,
ex.Message));
}
--count;
System.Threading.Thread.Sleep(rnd.Next(100, 500));
}
}
}
试图在 VisualStudio 中进行跟踪,但到目前为止我发现 EchoService2 控制器(链中的最后一个)从未命中。甚至没有调用应用程序构造函数。
在 IIS 日志文件中没有错误,除了几次我看到代码“- 500 0 64”。EventLog中也没有错误。
我相信数字 3 只是巧合,并且问题的根本原因在于其他问题(在 IIS 方面被阻止了?)。
我被困住了,没有想法了,任何帮助或提示如何跟踪 IIS 内部发生的事情都将受到高度赞赏!