Is Visual Studio Asp.Net Development Server Really Multi-Threaded? - asp.net

I'm debugging a WebProject in VS2010 that runs in the local dev server (cassini?). One of the aspx pages calls a ManualResetEvent.WaitOne() and another Page aspx page calls the ManualResetEvent.Set() (on the same Global object) to release the first page.
When I look at the thread list in VS2010 there seems to be lots of worker threads. However, the web server seems to halt processing anything while blocked by the ManualResetEvent.WaitOne() call. Therefor the ManualResetEvent.Set() does not load unless the .WaitOne() Times out.
What's going on here?
// Sample Code
Class SyncTest {
private System.Threading.ManualResetEvent eConnected =
new System.Threading.ManualResetEvent(false);
private bool isConnected;
public SyncTest ()
{
this.isConnected = false;
}
public void SetConnected(bool state)
{
isConnected = state;
if (state)
eConnected.Set();
else
eConnected.Reset();
}
public bool WaitForConnection(int timeout)
{
return eConnected.WaitOne(timeout);
}
}

The web server only processes one page at a time from each user.
If you want pages requested from one user to run in parallel, you have to make the pages (except one) sessionless.
Put EnableSessionState="false" in the #Page directive for a page to make it sessionless.
This of course means that you can't identify the request using the Session data. If you want to know who requested the page, you have to send it along in the request.

Related

ASP.Net Core HTTP Request Connections getting stuck

We have a simple application in ASP.NET Core which calls a website and returns the content. The Controller method looks like this:
[HttpGet("test/get")]
public ActionResult<string> TestGet()
{
var client = new WebClient
{
BaseAddress = "http://v-dev-a"
};
return client.DownloadString("/");
}
The URL which we call is just the default page of an IIS. I am using Apache JMeter to test 1000 requests in 10 seconds. I have always the same issue, after about 300-400 requests it gets stuck for a few minutes and nothing works. The appplication which holds the controller is completely frozen.
In the performance monitor (MMC) I see that the connection are at 100%.
I tried the same code with ASP.NET 4.7.2 and it runs without any issues.
I also read about that the dispose of the WebClient does not work and I should make it static. See here
Also the deactivation of the KeepAlive did not help:
public class QPWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
var request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
((HttpWebRequest)request).KeepAlive = false;
}
return request;
}
}
The HttpClient hast the same issue, it does not change anything
With dependency injection like recommended here there is an exception throw that the web client can't handle more request at the same time.
Another unsuccessful try was to change ConnectionLimit and SetTcpKeepAlive in ServicePoint
So I am out of ideas how to solve this issue. Last idea is to move the application to ASP.NET. Does anyone of you have an idea or faced already the same issue?

ASP.NET MVC, Is it possible to code a Response.AppendToLog in one place which will act on every Request?

I am using ASP.NET 4.7 and MVC5 with C# with IIS Express locally and published to Azure App Services.
I want to add something like:
Response.AppendToLog("XXXXX Original IP = 12.12.12.12 XXXXX");
Which adds an Original IP address to the request string in the "request" column in the web server log.
If I add this to a specific "get" Action this works fine. However I do not want to add this code to every Action. Is it possible to place it more centrally such that it gets executed on every "Get" / Request. This may be a simple question, but the answer alludes me at present
Thanks for any wisdom.
EDIT: Is this via Custom Action Filters?
if (filterContext.HttpContext.Request.HttpMethod=="GET")
{
Response.AppendToLog... //I know this will not work as Response not known.
}
You almost know the answer. Try handling OnActionExecuted that gets you the Response.
public class CustomActionFilter : ActionFilterAttribute, IActionFilter
{
void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
if(filterContext.HttpContext.Request.Method == HttpMethods.Get)
{
}
}
void IActionFilter.OnActionExecuted(ActionExecutedContext context)
{
var response = context.HttpContext.Response;
}
}
My solution to write out text:
filterContext.RequestContext.HttpContext.Response.AppendToLog("OrigIP");

Keep application users logged in for 20 Hours

We have a asp.net + MSSQL Server DB web based application with approx 100 users. Its hosted on our intranet on IIS7.0. We are using Forms Authentication
We need to keep the users (anyone who is logged in ) to be logged in for 20 Hours exactly. Means no one should be kicked out ( session time out ) of the application before 20 Hours even if he is idle.
We tried many of the suggested approaches like web config changes etc but nothing is working.
Our main question is : Will we have to do some code changes to keep the user sessions alive for this ( or any duration). Can someone suggest or point us to a solution?
Whenever you make a request to the server the session timeout resets. So you can just make an ajax call to an empty HTTP handler on the server, but make sure the handler's cache is disabled, otherwise the browser will cache your handler and won't make a new request.
KeepSessionAlive.ashx.cs
public class KeepSessionAlive : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
context.Response.Cache.SetNoStore();
context.Response.Cache.SetNoServerCaching();
}
}
.JS:
window.onload = function () {
setInterval("KeepSessionAlive()", 60000)
}
function KeepSessionAlive() {
url = "/KeepSessionAlive.ashx?";
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", url, true);
xmlHttp.send();
}

ASP .NET Application Life Cycle + Singleton Instance Life Time

Please considerer the following scenario :
I have created a full-web application by using the ASP .NET MVC 3 framework. Now my application is managed by a web server.
An HTTP request is received on the server-side of my application.
A class implementing the singleton design pattern is instanciated on server-side.
A response is sent to the browser.
Another HTTP request is received on the server-side of my application. Is the singleton instance used at step 2 still available on server-side ?
I read some information about the life cycle of an ASP .NET application on this page : http://msdn.microsoft.com/en-us/library/ms178473.aspx
But I am still not able to answer my question.
Thanks in advance for your future help
I have just made some tests under VS2010.
Here is the list of the main components of my project :
The Home controller containing an Index HttpGet action method.
The view resulting from the Index action method.
The SingletonTest class which implements the singleton design pattern.
Here is the code of the SingletonTest class :
public class SingletonTest
{
private int counter;
private static SingletonTest instance = null;
public int Counter
{
get
{
return counter;
}
}
public static SingletonTest Instance
{
get
{
if (instance == null)
instance = new SingletonTest();
return instance;
}
}
private SingletonTest()
{
counter = 0;
}
public void IncrementCounter()
{
counter++;
}
}
Here is the code of the Index action method :
public ActionResult Index()
{
SingletonTest st = SingletonTest.Instance;
st.IncrementCounter();
return View();
}
Here is the code of the view :
#SingletonTest.Instance.Counter
Here the test scenario I have followed :
The IIS server has been automatically launched by VS2010.
I have requested the /Home/Index/ URL then the value 1 has been displayed.
I have requested the /Home/Index/ URL then the value 2 has been displayed.
...
This test shows that the SingletonTest instance made at Step 1 is available when processing the next requests.
I guess that a memory space is allocated to my web application on the server.
Then I have stopped the IIS server and I have followed my test scenario again.
I have got the same results as before : 1, 2, ....
Even though the singleton may persist across multiple requests you need to be careful for exactly the reasons of your second test - when IIS is restarted or the app pool is recycled everything will be lost.
Are you sure that you need a singleton instance?
If you're looking to persist some state across all requests it would be better to use an external storage such as a database.
What about multi-instances of the same application that IIS Will Create to process the concurrent requests?
I thinks singleton Object will not be the same if IIS Create multiple instances of the same application in high traffic situation

Advantages/Disadvantages of increasing AppPool Timeout on Azure

I am just about to launch my ASP.NET MVC3 web app to production, however, as a complex app, it takes a LONG time to start up. Obviously, I don't want my users waiting over a minute for their first request to go through after the AppPool has timed out.
From my research, i've found that there are two ways to combat this:
Run a worker role or other process - which poll's the website every 19 minutes preventing the warm up.
Change the timeout from the default 20 minutes - To something much larger.
As Solution 2 seems like the better idea, i just wondered what the disadvantages would be of this, will I run out of memory etc.?
Thanks.
Could you use the auto-start feature of IIS? There is a post here that presents this idea.
You'd have IIS 7.5 and Win2k8 R2 with Azure OS family 2. You'd just need to be able to script/automate any setup steps and configuration.
I do this with a background thread that requests a keepalive URL every 15 minutes. Not only does this keep the app from going idle, but it also warms up the app right away anytime the web role or virtual machine restarts or is rebuilt.
This is all possible because Web Roles really are just Worker Roles that also do IIS stuff. So you can still use all the standard Worker Role startup hooks in a Web Role.
I got the idea from this blog post but tweaked the code to do a few extra warmup tasks.
First, I have a class that inherits from RoleEntryPoint (it does some other things besides this warm up task and I removed them for simplicity):
public class WebRole : RoleEntryPoint
{
// other unrelated member variables appear here...
private WarmUp _warmUp;
public override bool OnStart()
{
// other startup stuff appears here...
_warmUp = new WarmUp();
_warmUp.Start();
return base.OnStart();
}
}
All the actual warm up logic is in this WarmUp class. When it first runs it hits a handful of URLs on the local instance IP address (vs the public, load balanced hostname) to get things in memory so that the first people to use it get the fastest possible response time. Then, it loops and hits a single keepalive URL (again on the local role instance) that doesn't do any work and just serves to make sure that IIS doesn't shut down the application pool as idle.
public class WarmUp
{
private Thread worker;
public void Start()
{
worker = new Thread(new ThreadStart(Run));
worker.IsBackground = true;
worker.Start();
}
private void Run()
{
var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["http"]; // "http" has to match the endpointName in your ServiceDefinition.csdef file.
var pages = new string[]
{
"/",
"/help",
"/signin",
"/register",
"/faqs"
};
foreach (var page in pages)
{
try
{
var address = String.Format("{0}://{1}:{2}{3}",
endpoint.Protocol,
endpoint.IPEndpoint.Address,
endpoint.IPEndpoint.Port,
page);
var webClient = new WebClient();
webClient.DownloadString(address);
Debug.WriteLine(string.Format("Warmed {0}", address));
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
var keepalive = String.Format("{0}://{1}:{2}{3}",
endpoint.Protocol,
endpoint.IPEndpoint.Address,
endpoint.IPEndpoint.Port,
"/keepalive");
while (true)
{
try
{
var webClient = new WebClient();
webClient.DownloadString(keepalive);
Debug.WriteLine(string.Format("Pinged {0}", keepalive));
}
catch (Exception ex)
{
//absorb
}
Thread.Sleep(900000); // 15 minutes
}
}
}
Personally I'd change the timeout, but both should work: effectively they would both have the same effect of preventing the worker processes from shutting down.
I believe the timeout is there to avoid IIS retaining resources that aren't needed for servers with lots of Web sites that are lightly used. Given that heavily used sites (like this one!) don't shut down their worker processes I don't think you'll see any memory issues.

Resources