0

在我的 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 内部发生的事情都将受到高度赞赏!

4

0 回答 0