I am developing web application using (C#) and (ASP.NET Web API) and MS SQL 2008 R2 and hosting on IIS7 in Windows Server 2008, All APIs return data in JSON
When i call any API from any web browser and refresh the page to call again before the first call finishes it give me warning in the event viewer and after 0 to 5 minutes the worker process in the II7 stopped for about 2 minutes(hang) and all APIs calls from all users at the period of those 2 minutes don't work and event viewer give me an error:
The Warning in the event viewer
Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 6/5/2012 3:29:10 PM
Event time (UTC): 6/5/2012 1:29:10 PM
Event ID: 63adcb812864465cab58e9f870bcbb92
Event sequence: 5
Event occurrence: 1
Event detail code: 0
Application information:
Application domain: /LM/W3SVC/2/ROOT/AAA-2-129833765408950000
Trust level: Full
Application Virtual Path: /AAA
Application Path: C:\inetpub\wwwroot\AAA\
Machine name: MyMachine
Process information:
Process ID: 9860
Process name: w3wp.exe
Account name: NT AUTHORITY\NETWORK SERVICE
Exception information:
Exception type: HttpException
Exception message: The remote host closed the connection. The error code is 0x800704CD.
at System.Web.Http.WebHost.HttpControllerHandler.EndProcessRequest(IAsyncResult result)
at System.Web.Http.WebHost.HttpControllerHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Request information:
Request URL: My API URL
Request path: API Path
User host address: My IP
User:
Is authenticated: False
Authentication Type:
Thread account name: NT AUTHORITY\NETWORK SERVICE
Thread information:
Thread ID: 8
Thread account name: NT AUTHORITY\NETWORK SERVICE
Is impersonating: False
Stack trace: at System.Web.Http.WebHost.HttpControllerHandler.EndProcessRequest(IAsyncResult result)
at System.Web.Http.WebHost.HttpControllerHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
The Error in the event viewer
An unhandled exception occurred and the process was terminated.
Application ID: /LM/W3SVC/2/ROOT/AAA
Process ID: 9860
Exception: System.AggregateException
Message: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread.
StackTrace: at System.Threading.Tasks.TaskExceptionHolder.Finalize()
InnerException: System.Web.HttpException
Message: The remote host closed the connection. The error code is 0x800704CD.
StackTrace: at System.Web.Http.WebHost.HttpControllerHandler.EndProcessRequest(IAsyncResult result)
at System.Web.Http.WebHost.HttpControllerHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Code behind
public class contentController : ApiController { dynamic json = new JsonObject();
// GET /api/v1/content
[HttpGet]
public IEnumerable<ME_API_V1.Models.Content> GetContent()
{
Request.Headers.Add("Accept", "application/json");
List<ZMSLibrary.ME.Models.Content> contentList = new List<ZMSLibrary.ME.Models.Content>() ;
try
{
//DateTime CurrentDateTime = DateTime.Now;
var querystring = this.Request.RequestUri.Query;
var parameters = HttpUtility.ParseQueryString(querystring);
string userID = parameters["userID"];
string countryCode = parameters["countryCode"];
string language = parameters["language"];
string categoryName = parameters["categoryName"];
string subcategoryID = parameters["subcategoryID"];
string count = parameters["count"];
string start = parameters["start"];
string platform = parameters["platform"];
string imageSize = parameters["imageSize"];
//Check IP Restiriction
Restriction restiriction = new Restriction(ConfigurationManager.ConnectionStrings["AppSQLConnection"].ToString());
bool allowedCheck = restiriction.IsUserAllowed(userID);
if (!allowedCheck)
{
dynamic json = new JsonObject();
json.message = "Authorized Only for Mobinil in Egypt";
var msg = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden);
msg.Content = new StringContent(json.ToString());
msg.Content.Headers.ContentType.MediaType = "application/json";
throw new HttpResponseException(msg);
}
else
{
//Validate input data
if (InputValidation.isValidUserid(userID) &&
InputValidation.isValidCountryCode(countryCode) &&
InputValidation.isValidLanguage(language) &&
InputValidation.isValidCategory(categoryName) &&
InputValidation.isValidUserid(subcategoryID) &&
InputValidation.isValidPlatform(platform)
)
{
if (!InputValidation.isValidImageSize(imageSize))
{
imageSize = "high";
}
if (!InputValidation.isValidUserid(count) || !InputValidation.isValidUserid(start))
{
start = WebConfigurationManager.AppSettings["DefaultStart"];
count = WebConfigurationManager.AppSettings["DefaultCount"];
}
ContentOperations contentOperations = new ContentOperations();
contentList = contentOperations.getContent(subcategoryID, categoryName, count, start, countryCode, userID, ConfigurationManager.ConnectionStrings["AppSQLConnection"].ToString(), WebConfigurationManager.AppSettings["FileFolderName"], imageSize, language, platform);
if (contentList != null)
{
List<ME_API_V1.Models.Content> contentOutputList = new List<ME_API_V1.Models.Content>();
foreach (ZMSLibrary.ME.Models.Content c in contentList)
{
File tempFile = new File();
ME_API_V1.Models.Content cTemp = new ME_API_V1.Models.Content();
cTemp.contentID = int.Parse(c.ContentID);
if (c.Rating == "1")
cTemp.userRating = "Like";
else if (c.Rating == "0")
cTemp.userRating = "Dislike";
cTemp.date = String.Format("{0:G}", c.ContentDate);
//if (c.Provider.ContentProviderName != "") //to make the value null instead of ""
cTemp.providerName = c.Provider.ContentProviderName;
//if (c.Provider.ContentProviderIcon != "")
cTemp.providerIconURL = c.Provider.ContentProviderIcon;
//if (c.Provider.ContentProviderImage != "")
cTemp.providerImageURL = c.Provider.ContentProviderImage;
if (language == "AR")
{
//if (c.ContentArabicTitle != "")
cTemp.title = c.ContentArabicTitle;
//if (c.ContentArabicSubTitle != "")
cTemp.subtitle = c.ContentArabicSubTitle;
//if (c.ContentArabicDescription != "")
cTemp.description = c.ContentArabicDescription;
}
else
{
//if (c.ContentEnglishTitle != "")
cTemp.title = c.ContentEnglishTitle;
//if (c.ContentEnglishSubTitle != "")
cTemp.subtitle = c.ContentEnglishSubTitle;
//if (c.ContentEnglishDescription != "")
cTemp.description = c.ContentEnglishDescription;
}
if (categoryName == "Music")
{
foreach (ContentFile cf in c.ContentFiles)
{
if (cf.FileType.FileTypeName == "Icon")
tempFile.iconURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "Image")
tempFile.imageURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "Clip_High")
tempFile.highVideoURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "Clip_Low")
tempFile.lowVideoURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "Tone")
tempFile.toneURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "Song")
tempFile.songURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "YouTube")
tempFile.youtubeID = cf.ContentFileName;
}
}
else if (categoryName == "News")
{
foreach (ContentFile cf in c.ContentFiles)
{
if (cf.FileType.FileTypeName == "Icon")
tempFile.iconURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "Image")
tempFile.imageURL = cf.ContentFileName;
}
}
else if (categoryName == "Videos")
{
foreach (ContentFile cf in c.ContentFiles)
{
if (cf.FileType.FileTypeName == "Icon")
tempFile.iconURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "Image")
tempFile.imageURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "Video_High")
tempFile.highVideoURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "Video_Low")
tempFile.lowVideoURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "YouTube")
tempFile.youtubeID = cf.ContentFileName;
}
}
else if (categoryName == "Applications")
{
foreach (ContentFile cf in c.ContentFiles)
{
if (cf.FileType.FileTypeName == "Icon")
tempFile.iconURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "Image")
tempFile.imageURL = cf.ContentFileName;
else if (cf.FileType.FileTypeName == "App_Android" || cf.FileType.FileTypeName == "App_Nokia" || cf.FileType.FileTypeName == "App_Blackberry" || cf.FileType.FileTypeName == "App_iPhone")
{
tempFile.appURL = cf.ContentFileName;
}
}
}
cTemp.files = tempFile;
contentOutputList.Add(cTemp);
}
return contentOutputList;
}
}
if (contentList == null)
throw new Exception();
else
{
json.message = "Wrong or missing data";
var msg = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);
msg.Content = new StringContent(json.ToString());
msg.Content.Headers.ContentType.MediaType = "application/json";
throw new HttpResponseException(msg);
}
}
}
catch (Exception ex)
{
if (ex is HttpResponseException)
{
throw;
}
else
{
json.message = "Error in System";
var msg = new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError);
msg.Content = new StringContent(json.ToString());
msg.Content.Headers.ContentType.MediaType = "application/json";
throw new HttpResponseException(msg);
}
}
}
}
I see that you have two foreach loop, if this are big ones and your program is stack there looping, then there it is your hang.
You can try something like that to detect the disconnection and stop this delay.
foreach (ZMSLibrary.ME.Models.Content c in contentList)
{
if (!Response.IsClientConnected){
HttpContext.Current.Response.End();
return;
}
foreach (ContentFile cf in c.ContentFiles)
{
}
}
Also I do not know if you have the session open, if you are not use it, turn it off, and use some other synchronization if you add data - eg use mutex with mutex name a unique code of the work.
The remote host closed the connection.
This is actually only say that you make a refresh as you describe with out first get results, so the thread after finish, and try to send back the output he find the connection close.
User contributions licensed under CC BY-SA 3.0