Prevent ASP.Net AppDomain Unload - c#

As described here, I'm writing a WinForms GUI that is run in an ASP.Net AppDomain.
However, whenever Web.config or the bin folder is modified, ASP.Net unloads the AppDomain, and the entire program dies.
Is there any way to prevent this?
2nd EDIT: In my EXE, I create the AppDomain by calling ApplicationHost.CreateApplicationHost and pass it a type in my EXE that launches the GUI.
EDIT: I'm already aware that this is a horrible design.
Does anyone have a sane alternatives?
The program tracks accounts for a non-profit organization in a typed dataset.
It needs to send bills by email, and I'm using ASPX files to generate the emails. (I'd rather not change that, unless there's a very nice alternative; the templates have already been written)
The email templates are ASPX files that are deployed in a subfolder; that subfolder becomes the ASP.Net application and has the executable in its bin directory for ASP.Net to load all of my code into its AppDomain.
The typed dataset must be accessed by both the UI and the ASPX files, and I don't want to download the data from SQL server twice

This is core to ASP.Net - if the web.config is changed, the AppDomain is recycled. If the machine.config is changed, all AppDomains are recycled.
However, you can disable this. Turn on "Disable Recycling on Configuration Changes" for the application pool you are interested in in the IIS control panel.
alt text http://img138.imageshack.us/img138/9938/iisdisablerecycle.png

See this question: How to prevent an ASP.NET application restarting when the web.config is modified?

I've noticed that your first question is dated Oct 29. I know it's far off on the development track...
But just out of curiosity: Why not use T4 templates?
It's simple, fast, you can edit pretty much like an ASPX page, and it runs in whatever AppDomain you are.

Related

Copy Files to the output directory on an Azure WebRole

We have an azure Webrole which we call as an API from other applications to convert webpages into a rendered byte array which we then attach as a pdf into emails. We do this using ABCpdf.
For our latest project we have to use a second engine from ABC (ABCGecko) in order to render our pages correctly. The ABCGecko engine requires manually copying to the output directory after build occurs, it doesn't happen automatically.
For a normal application this is no issue, I simply copy the required folder (XULRunner_38 for anyone who uses ABC) into the release after building but I can't figure out how to do this for an Azure WebRole and there doesn't seem to be anything much in the way of help from what I can see in google searches.
I'm assuming I either have to build the role and then adjust the package before I deploy, or deploy the role and then copy the folder across after. I can't figure out how to do this though.
If anyone has any ideas or has needed to manually copy files to an Azure Webrole in the past then I would greatly appreciate your help. Also I should mention that we use Visual Studio as our IDE and publish from within there in case that matters to anyone.
Azure web (and worker) roles allow you to define startup tasks, which allows you to call a script (e.g. powershell script, batch file) which can then perform actions such as copying files.
Oh, and if you don't want it to attempt copying in the event a role instance reboots, you'd need to do something like leaving yourself a "breadcrumb" somewhere to signal that you've already done your init work.
What you don't want to ever do is manual copying of content to your role instances. The moment those instances are updated (e.g. new Host OS update) or they're moved to another physical host, you'll lose any of the files you manually copied.
This is all independent of any IDE (aside from general support for the script language you're writing in), since your startup task is going to execute on each web role instance when it starts up.
More details about startup tasks are here.

How to avoid ASP MVC application from getting freeze and throwing exception while replacing its entire web files?

In our ASP.NET MVC application, we have a 'load' button which the user can click to update the current application to its newer version. During the loading of newer version, all the web files are removed and new files are copied back and this process will take 1-2 minutes.
Issue: Since the files are getting removed and replaced back, my application will stuck during the process and throw an exception. Once the files are replaced back, everything works fine after a simple reload.
Please give me some suggestions how we can avoid the freezing of the application during the loading process ? (like showing a model popup in between, and once the files are copied back, do a reload, etc). Any ideas/suggestions are welcome. Thanks
You need to do something like this.
ASP.NET 2.0 - How to use app_offline.htm
copy the app_offline.html to the root of your site.
copy the application out
delete the app_offline.html
this will return the offline page for all requests to your application while you are copying the files out.
Once you delete app_offline, your application will be available.

Using AppDomainSetup.ShadowCopyDirectories in IIS

I've got a ton of DLLs used by my website. Most of them never change, but I frequently change 1 of them.
Every time I do the site is down for about 5 minutes while IIS restarts. I'd like to reduce this.
I've read about shadow copying being slow when you have a lot of DLL files so I'd like to disable it in most cases, but I do want to use it on my frequently modified DLL so I can change that without having to stop IIS.
The documentation on shadow copying seems to presume you are setting it up before the AppDomain is created, but IIS handles the creation of the AppDomain so I don't know how to use the AppDomainSetup.ShadowCopyDirectories property to tell it not to do any shadow copying in the main /bin folder and only shadow copy things in the /bin/changesFrequently folder. Can I set this in web.config somehow? Is there a way to run c# code in IIS before the shadowcopy process starts?

Debug ASP.NET CMS

We're developing a custom Content Management System in ASP.NET 4.0, using Team Foundation Server for source control. The database is hosted in a remote server, whereas the debug is done locally, thus new content (aspx pages) created by each member of the team is stored in our local computers and unavailable for other team members. I don't think adding those files to source control is the best approach, but the only other way I see is deploying to an external IIS for debugging.
Have you already worked with this scenario? Wwhat do you think is the best option? Thanks in advance
thus new content (aspx pages) created by each member of the team is stored in our local computers and unavailable for other team members ... I don't think adding those files to source control is the best approach
I really wonder why you think that is a bad idea... I think adding created code in your source control system is the very best thing to do.
What do you think happens if a computer stops working, gets stolen, etc? How do you obtain the file again? Store every file that is crucial to your system in a source control system.
I guess you can have a "tools" folder in project structure where you keep all of your test pages. Then when project is built that folder can be excluded from copying.
For example when Release build is executed "tools" folder is excluded, while Debug builds leave it in the project.
It really depends how do you guys work, how many of you there are, how often do you do delivery cycle - but generally garbage of test pages tends to grow all over the place (same as commented out code) if there is no systematic approach and whole project team chips in.

how to restart asp.net application besides modifying web.config

Is there a recommended way to bounce an asp.net application besides touching web.config from inside the application? is HttpRuntime.UnloadAppDomain(); the preferred way to do this ? and if so where do you do this? In the unload of a page or some other place in the application?
Touching web.config from inside an application is a bad idea, IMO. Also, the idea of having a file that you modify is a little hackney, IMO.
The documentation specifically states that UnloadAppDomain will shut the application down:
UnloadAppDomain allows programmatic shutdown of unused applications.
You should be able to make this call anywhere in the application. Mind you, you might get a SecurityException, so make sure that the runtime gives you the appropriate permissions (you might want to put this in a library and make a call and then set the library up in the GAC with evidence to give it full trust).
If this is .NET 2.0 or greater, then you can add in an "App_offline.htm" file, make a request to the server, remove it, and then make another request to the server.
This sequence of events will force ASP.NET to unload the application for as long as the app_offline.htm file exists in the folder.
Scott Guthrie's blog entry on it:
http://weblogs.asp.net/scottgu/archive/2005/10/06/426755.aspx
this code work for me. just call it to reload application.
System.Web.HttpRuntime.UnloadAppDomain();
Read more
This method will just unload our application. If you just put this method in an ASP.NET web button you are totally done. So when will our application reloaded? Actually if you click your button it will first launch our method and unload application. Further on the web page we are on at that moment will be reloaded as well, because we just clicked a button and the web page should refresh. After launching our method the page refresh process will cause our application to reload as well.
You can stop and start the Application Pool associated with the app as well.
You can do this by calling the HttpRuntime.ShutdownAppDomain method (you will need to use reflection to invoke it, since it is a private static method)
See How to restart an IIS Worker Process programmatically (i.e. shutdown the current ASP.NET Domain) for an example of how I use this method in a 'Restart' REST API
You could safely restart a web application by creating or renaming a folder at run time under the application directory. Obviously you need to give the user assigned to run the application "modify" rights to the web directory or to a sub directory under it.
the method is mentioned at
http://www.bartlannoeye.be/blog/restarting-a-.net-web-application-without-restarting-iis
I used the following code to do it in my case. Modify it to work on a "writable" sub-directory
protected void RestartButton_Click(object sender, EventArgs e)
{
//restart web app (instead of iisreset)
DirectoryInfo dir = new DirectoryInfo(Server.MapPath("restart"));
if (dir.Exists)
{
Directory.Move(dir.FullName, dir.FullName + "ed");
}
else
{
DirectoryInfo dired = new DirectoryInfo(Server.MapPath("restarted"));
if (dired.Exists)
{
Directory.Move(dired.FullName, dir.FullName);
}
else
{
Directory.CreateDirectory(dir.FullName);
}
}
}
If you don't want to stop and start the app pool you can always recycle it.

Categories