How can I know the number of IIS threads consumed at a given time by my ASP.NET Web API service?
I can count .NET CLR threads of the running application by the below code snippet:
int number = Process.GetCurrentProcess().Threads.Count;
but my question is about IIS threads.
IIS v8.5, Windows Server 2012
In IIS a service (ASP.NET application) is running using an application pool. So if the name of the application pool is known at runtime, you can determine the number of threads for your application pool:
var applicationPoolName = "YOUR APPLICATION POOL";
using (var serverManager = new Microsoft.Web.Administration.ServerManager())
{
var applicationPool = serverManager.ApplicationPools[applicationPoolName];
var threadsCount = applicationPool
.WorkerProcesses
.Select(p => Process.GetProcessById(p.ProcessId))
.SelectMany(p => p.Threads.Cast<ProcessThread>())
.Count();
}
Related
Creating an event using the create event API call in Microsoft Graph with the .NET SDK. This is my code:
private async Task addEvent(Event #event)
{
using(var task = Task.Run(async() => await client
.Me
.Calendars[calendarID]
.Events.Request()
.AddAsync(#event)))
{
while (!task.IsCompleted)
Thread.Sleep(200);
}
}
This is running and working as expected on my local machine and on IIS in a VM by another provider - has been for about 6 months now.
However, when this runs on an Azure App Service, it doesn't throw an exception but no events are actually created. Read-only calls to get events and calendars work, but this one just doesn't. Any ideas appreciated - maybe there's a setting in an app service?
The following code fail when executed on an Azure Guest OS Family 5 (Cloud Service webrole running Windows Server 2016):
using (var serverManager = new ServerManager())
{
ApplicationPool applicationPool = serverManager.ApplicationPools.Add(name);
applicationPool.AutoStart = true;
applicationPool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
applicationPool.ManagedRuntimeVersion = "v4.0";
// START ISSUE:
applicationPool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser;
applicationPool.ProcessModel.UserName = username;
applicationPool.ProcessModel.Password = userPassword;
applicationPool.ProcessModel["idleTimeoutAction"] = 1;
// END ISSUE
serverManager.CommitChanges();
}
Exception:
System.Runtime.InteropServices.COMException: The directory property
cannot be found in the cache.
More info
The exception is thrown at CommitChanges, but only when we have the code setting AppPool identity (the 4 lines between START ISSUE and END ISSUE). So this issue happen when setting AppPool identity.
This code have been in production for some years, working fine on on-prem Windows Servers and Azure Guest OS Family 4. We run the code with elevated privileges (using <Runtime executionContext="elevated"/>) and from the command line with administrative privileges. Same exception, but only on WinSrv2016 Azure cloud.
Workaround:
If we regenerate the machine keys on the deployment as described here, we stop experiencing this issue.
Question:
Is this an known issue on OS Family 5 Azure cloud service deployments that is being addressed? Any less obtrusive suggestions to work around this?
I also tested it on my side. When I set the App Pool Identity manually(Remote desktop to Web Role and reset the Identity using IIS Manager), I can reproduced the Keyset does not exist issue.
As described in the article which you post, the issue is caused by machine keys corrupt. I suggest you log this issue on cloud service feedback page.
https://feedback.azure.com/forums/169386-cloud-services-web-and-worker-role
We have a few standard websites in our azure subscription. We are trying to automate some tasks, one being creating a site in Azure. We are using the 'Microsoft Azure Web Sites Management Library' from Nuget. We are using the below code, but in spite of telling it dedicated, it always gets created as a Free site and not Standard.
domain is a string containing the domain for the site. hostName is a string containing the domain + 'azurewebsites.net', domain has periods stripped for hostName. ws is a WebSpace object that we retrieved from calling previous Azure methods for our subscription.
var newSite = new WebSiteCreateParameters();
newSite.Name = domain;
newSite.HostNames.Add(hostName);
newSite.ComputeMode = WebSiteComputeMode.Dedicated;
newSite.ServerFarm = "DefaultServerFarm";
newSite.WebSpaceName = ws.Name;
newSite.WebSpace = new WebSiteCreateParameters.WebSpaceDetails()
{
GeoRegion = ws.GeoRegion,
Name = ws.Name,
Plan = ws.Plan
};
var r = await AzureClient.WebSites.CreateAsync(
ws.Name,
newSite,
new System.Threading.CancellationToken()
);
Can you take a look at this sample in github:
https://github.com/btardif/AzureWebsitesAPISamples
To create a site in standard mode you will first need to create the Web Hosting Plan (WHP) and then assign the website to this WHP.
Web Hosting Plans AKA ServerFarm have a SKU property Size and Instance count.
In my MVC web application, I use a WCF services.
Once the user sign In, I need to update the "lastLoggedOnDate" for the user as a background WCF service call.
I want the user login process to be completed and not wait for this service call.
How can I do this?
Person personObj = null;
using (var services = new ServiceFactory())
{
personObj = services.Person.GetUserByLoginDetails(user.Username,-parameters-);
}
--Authentication process --
--If authentication success --
--BACKGROUND CALL TO WCF service ??
In case the background task spans the boundary of a single HTTP request/response, there are at least two options to deal with this:
Delegate the pending task to a separate process like Windows Service (a similar question).
Create a static task scheduler (singleton object), which would run the task inside the ASP.NET process space. More details: Long Running Background Tasks in Asp.Net MVC3.
I see Microsoft have released Application Initialization as part of IIS 8.0. Unfortunately it isn't enabled in the Web Role by default. (by that I mean, "Application Initialization" as a feature of the web server role is not enabled. I know the Web Role has IIS 8.)
Does anyone know how I can enable this from a start-up script? I've already a number of start-up scripts, but I'm not sure how to add a server role feature.
The module itself appears inside Server Manager under "Server Roles" -> "Web Server (IIS)" -> "Web Server" -> "Application Development" -> "Application Initialization".
It's a shame that this isn't enabled by default as it will be very useful.
thanks
Kris
First you'll need to install the feature using a startup task:
PKGMGR.EXE /iu:IIS-ApplicationInit
And then you'll need to configure your site in IIS (startMode and preloadEnabled):
public class WebRole : RoleEntryPoint
{
public override void Run()
{
using (var serverManager = new ServerManager())
{
var mainSite = serverManager.Sites[RoleEnvironment.CurrentRoleInstance.Id + "_Web"];
var mainApplication = mainSite.Applications["/"];
mainApplication["preloadEnabled"] = true;
var mainApplicationPool = serverManager.ApplicationPools[mainApplication.ApplicationPoolName];
mainApplicationPool["startMode"] = "AlwaysRunning";
serverManager.CommitChanges();
}
base.Run();
}
public override bool OnStart()
{
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
return base.OnStart();
}
}
I wrote a blog post about this and you can find a sample application on GitHub.
The web role absolutely has IIS 8.0 installed. Id you change the web role to OSVersion=3, it will deploy your app to a Windows Server 2012 image with IIS 8.0.
If you mean the VM (Azure IaaS)? What I would do is start from Windows Server 2012, remote desktop in, install the core server as you want, sysprep it, capture the image. This way you have it for re-use in your Azure Image Gallery. Then you can spin up many VMs from this base image with IIS 8.0 already set up/installed etc.