在一台服务器上启动后,Web服务线程立即死亡 [英] Web service thread dies immediately after starting on one server

查看:72
本文介绍了在一台服务器上启动后,Web服务线程立即死亡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#中开发了一个ASP.NET(.asmx)Web服务。在它返回之前,它启动一个线程(通过线程池和一个简单的线程尝试)来执行Web请求。在创建Web请求之前,我需要大约1-2秒的延迟。我已经尝试过睡眠,定时器,甚至是数百万的for循环计数。在我的开发服务器(Server 2012 R2)上,它始终有效。在距离不同国家数千英里的客户服务器上,以及Server 2012 R2上,它的工作时间不到10%。根据我的日志记录,线程在Web请求之前的延迟期间结束。什么可以杀死它? ASP.NET是否认为它不活跃? 

代码:



我在C#中开发了一个ASP.NET(.asmx)Web服务。在它返回之前,它启动一个线程来执行Web请求。在创建Web请求之前,我需要大约2秒的延迟。我已经尝试过睡眠,定时器,甚至是数百万的for循环计数。在我的开发服务器上,它始终有效。在客户的服务器上,它的工作时间不到10%。根据我的日志记录,线程在Web请求之前的延迟期间结束。什么可以杀死它? ASP.NET是否认为它不活跃?
它记录TesterRequest:WAIT之前然后系统异常线程被中止(参见下面的代码),当然没有别的。
相关代码 - 下面是for循环版本(放入for循环只是为了在睡眠和计时器方法失败后进行测试,在经过时间完成之前中止):

static void ThreadProc(object p_tcti)
{

//通过HttpWebRequest调用测试器内的方法

int nSleep = 606111000; // 2000;
LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+。+TesterRequest:在WAIT之前+ nSleep.ToString());

int nDummy = 0;
for(int n = 0; n< nSleep; n ++)
{
nDummy = n;
}

LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+。+TesterRequest:WAIT之后+ nDummy .ToString()+向测试人员创建Web请求。);
HttpWebRequest reqWeb =(HttpWebRequest)WebRequest.Create(tcti.m_strURL);
LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+。+TesterRequest:创建了Web请求。);
reqWeb.Method =GET;
//reqWeb.MaximumAutomaticRedirections = 4;
//reqWeb.MaximumResponseHeadersLength = 4;
reqWeb.UserAgent =ABRWebService /1.0;
//做吧!这将阻止最多40秒
string strStatus =;
reqWeb.Timeout = 40000;
try
{
HttpWebResponse resWeb =(HttpWebResponse)reqWeb.GetResponse();
// LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+。+TesterRequest:来自测试者网络请求的响应。);
if(resWeb.StatusCode!= HttpStatusCode.OK)
{
strStatus = resWeb.StatusDescription;
LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+。+TesterRequest FAILED++ strStatus);
}
resWeb.Close();
}
catch(WebException we)
{
//忽略超时,因为我们没有给出关于
//响应的回复。
tcti.m_strResult = we.Message;
if(we.Status!= WebExceptionStatus.Timeout)
{
LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+ 。+TesterRequest Web例外:+ we.Message +请求:+
tcti.m_strResult +,URL:+ tcti.m_strURL);
if(!strStatus.Equals())
LogMessage(Status:+ strStatus);
LogMessage(TesterRequest FAILED++ DateTime.Now);
// RWC不要扔掉我们;
}
}
catch(exception ex)
{
LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString ()+。+TesterRequest Exception:+ ex.Message);
}

LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+。+TesterRequest Succeeded。);

}

public TesterRequest(string p_strURL)
{{
try
{
TesterCommThreadInfo tcti = new TesterCommThreadInfo() ;
tcti.m_strURL = p_strURL;
LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+。+TesterRequest:开始排队一个线程以触发程序下载。);
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc),tcti);
// Service.LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+。+TesterRequest:Begin - 创建并启动一个新线程来触发程序下载。);
// 6/4/18从线程池改为简单线程,以提高可靠性。
// Thread tr = new Thread(()=> ThreadProc(tcti));
//tr.Start();
//Service.LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+。+TesterRequest:End - 创建并启动一个新线程来触发程序下载。);
LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+。+TesterRequest:End排队一个线程来触发程序下载。);
}
catch(ThreadAbortException tae)
{
Service.LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+ 。+TesterRequest线程中止异常创建和/或启动程序下载的新线程:+ tae.Message);
}
catch(AppDomainUnloadedException aue)
{
Service.LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+ 。+TesterRequest App Domain Unloaded Exception为程序下载创建和/或启动新线程:+ aue.Message);
}
catch(exception ex)
{
Service.LogMessage(DateTime.Now.ToString()+ms:+ DateTime.Now.Millisecond.ToString()+ 。+TesterRequest异常创建和/或启动程序下载的新线程:+ ex.Message);
}
}
}
}

我尝试过:

尝试改变从线程池线程到简单线程。尝试了三种不同的延迟。第一个延迟是系统线程线程睡眠。然后我尝试了一个系统计时器。最后,在强烈尝试消除我的线程处于非活动状态的外观时,我使用for循环计算数百万为dealy。

解决方案

< blockquote>您的ASP.NET代码仅在完成传入请求所花费的时间内运行。如果你解雇并忘记一个线程,一旦ASP.NET向客户端返回响应,该线程将被终止。



你的代码必须等待在将任何内容返回给客户端之前完成其工作的线程。


I have developed an ASP.NET (.asmx) webservice in C#. Just before it returns, it starts a thread (have tried via the threadpool and a simple thread) to perform a web request. Before creating the web request, I need a delay of about 1 - 2 seconds. I have tried a Sleep, a Timer, and even a for loop counting into the millions. On my development server (Server 2012 R2) it works all of the time. On the customer's server thousands of miles away in a different country, but also on Server 2012 R2, it works less than 10% of the time. According to my logging, the thread ends sometime during the delay, before the web request. What could be killing it? Does ASP.NET decide it is not active?

Code:



I have developed an ASP.NET (.asmx) webservice in C#. Just before it returns, it starts a thread to perform a web request. Before creating the web request, I need a delay of about 2 seconds. I have tried a Sleep, a Timer, and even a for loop counting into the millions. On my development server it works all of the time. On the customer's server, it works less than 10% of the time. According to my logging, the thread ends sometime during the delay, before the web request. What could be killing it? Does ASP.NET decide it is not active?
It logs "TesterRequest: Before WAIT of" then the System exception "Thread was being aborted" (see code below), then of course nothing else.
Relevant Code - Below is the for loop version (put in the for loop just to test after sleep and timer methods failed to be sustained, were aborted before elapsed time was completed): 

static void ThreadProc(object p_tcti)
{

        // Calls a method inside the tester via HttpWebRequest

            int nSleep = 606111000; // 2000;
            LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest: Before WAIT of " + nSleep.ToString());

            int nDummy = 0;
            for (int n = 0; n < nSleep; n++)
            {
                nDummy = n;
            }

            LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest: After WAIT " + nDummy.ToString() + " creating web request to tester.");
            HttpWebRequest reqWeb = (HttpWebRequest)WebRequest.Create(tcti.m_strURL);
            LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest: Created the web request.");
            reqWeb.Method = "GET";
            //reqWeb.MaximumAutomaticRedirections = 4;
            //reqWeb.MaximumResponseHeadersLength = 4;
            reqWeb.UserAgent = "ABRWebService /1.0";
            // Do it!  This will block for up to 40 seconds
            string strStatus = "";
            reqWeb.Timeout = 40000;
     try
     {
                HttpWebResponse resWeb = (HttpWebResponse)reqWeb.GetResponse();
                //       LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest: Received response from the tester web request. ");
                if (resWeb.StatusCode != HttpStatusCode.OK)
                {
                    strStatus = resWeb.StatusDescription;
                    LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest FAILED" + " " + strStatus);
                }
                resWeb.Close();
            }
            catch (WebException we)
            {
                // Ignore timeouts since we don't give a about the
                // response.
                tcti.m_strResult = we.Message;
                if (we.Status != WebExceptionStatus.Timeout)
                {
                    LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest Web Exception:  " + we.Message + "  Request:  " +
                    tcti.m_strResult + ", URL:  " + tcti.m_strURL);
                    if (!strStatus.Equals(""))
                        LogMessage("Status: " + strStatus);
                    LogMessage("TesterRequest FAILED" + " " + DateTime.Now);
                    // RWC don't throwthrow we;
                }
            }
            catch (Exception ex)
            {
                LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest Exception:  " + ex.Message);
            }

            LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest Succeeded.");

}

public TesterRequest(string p_strURL)
{       {
  try
  {
                TesterCommThreadInfo tcti = new TesterCommThreadInfo();
                tcti.m_strURL = p_strURL;
                   LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest: Begin queueing a thread to trigger program download.");
                   ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), tcti);
               // Service.LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest: Begin - Create and launch a new thread to trigger program download.");
                // 6/4/18 changed to simple thread from thread pool for better reliability.
                //Thread tr = new Thread(() => ThreadProc(tcti));
                //tr.Start();
                //Service.LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest: End - Create and launch a new thread to trigger program download.");
                   LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest: End queued a thread to trigger program download.");
            }
            catch (ThreadAbortException tae)
            {
                Service.LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest Thread Abort Exception Creating and/or launching new thread for program download: " + tae.Message);
            }
            catch (AppDomainUnloadedException aue)
            {
                Service.LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest App Domain Unloaded Exception Creating and/or launching new thread for program download: " + aue.Message);
            }
            catch (Exception ex)
            {
                Service.LogMessage(DateTime.Now.ToString() + " ms: " + DateTime.Now.Millisecond.ToString() + ". " + "TesterRequest Exception Creating and/or launching new thread for program download: " + ex.Message);
            }
        }
    }
}

What I have tried:

Tried changing from threadpool thread to simple thread. Tried three different delays. First delay was a System Threading Thread Sleep. Then I attempted a System Timer. Finally, in a strong attempt to eliminate the appearance my thread was inactive, I used a for loop counting into the millions for the dealy.

解决方案

Your ASP.NET code is only running for the time it takes to fulfill the incoming request. If you "fire and forget" a thread, that thread is going to be terminated once ASP.NET returns a response to the client.

Your code has to wait for the thread to finish its work before returning anything to the client.


这篇关于在一台服务器上启动后,Web服务线程立即死亡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆