Now I can start stealing music again ;)
Now I can start stealing music again ;)
Posted at 01:24 PM | Permalink | Comments (0) | TrackBack (0)
Miserable Failure. Got the idea for this from here. Jimmy Carter was the real Miserable Failure!! Not George Bush! His administration has saved us from the bubble that Clinton encouraged through the 90s. Just watch Startup.com. Can you name the President that was in that movie???
Rant over.
Posted at 09:29 AM | Permalink | Comments (0) | TrackBack (0)
Wow, three posts in one night. I've been busy tonight.
I saw a post on ASP.Net asking for an example of how to access the Request, Response, Server, Session and Application Objects in a .Net class. The answer is to use the HttpContext in you class. I thought I would post a quick example here.
Imports System.Web
Public Class MyClass
Public Shared Sub MyFunction()
Dim ctx As HttpContext = HttpContext.Current
Dim strMyVar1 As String = ctx.Request("MyVar1")
Dim strMyVar2 As String = ctx.Request("MyVar2")
End Class
It's as simple as that.
Posted at 11:17 PM | Permalink | Comments (0) | TrackBack (0)
Well, Survivor is finally over. I am sooo happy that Lil did not win although I am not exactly happy that Sandra won. Believe it or not, I was rooting for John. He played the game great and he was a complete snake. That stunt with his grandma was hysterical. My two cents.
Posted at 10:27 PM | Permalink | Comments (0) | TrackBack (0)
In the application I am currently working on, I have data that does not change very often. The web application has product catalog and affiliate data that displays on pretty much every page of the site. This data does not change all that often. Even if it does, it will change, at most, once a day. In order to save expensive database resources, this data is stored in the ASP.Net Global Cache.
On my company’s web site, we have thousands of affiliates that direct traffic to us. Based on the affiliate we change certain display elements on our web site. What I did is create a class that encapsulates all functions and data that we need to display for an affiliate. Once an instance this class is loaded for an affiliate, it is stored in the global cache. This saves us from having to go back to the database for the affilate's data each time we need it in the application. It is especially good for affiliates that send us thousands of users in a single hour. I also set up configuration settings that control how old the data in the Cache Object can get so that when the data is changed, it will refresh itself. In addition, since the web site has thousands of affiliates, it would be a memory hog to hold all the affilliates data in the Cache Object taking up memory. If an affiliate’s data is only used once a day, then it is ok to go the the database that one time to retrieve the data. The main goal I have for caching in my application is to prevent hundreds of requests for the same data at the same time. Therefore, I usually set the AFFILIATE_CACHE_TIMEOUT setting to 30 minutes or less. I also have a setting that can turn caching of affiliate data off completely.
Here is how the code looks for working with the Cache:
Dim myAffiliate as Affilate
Dim blnCacheAffiliateData As Boolean = ConfigurationSettings.AppSettings.Get("CACHE_AFFILIATE_DATA")If blnCacheAffiliateData Then
If IsNothing(Cache("Affiliate_" & intAffiliateID)) And blnCacheAffiliateData Then
Dim intAffiliateCacheInterval As Integer = ConfigurationSettings.AppSettings.Get _
("AFFILIATE_CACHE_TIMEOUT")
Cache.Insert("Affiliate_" & intAffiliateID, New Affiliate(intAffiliateID), Nothing, _
DateTime.Now.AddMinutes(intPartnerCacheInterval), Nothing)
End If
myAffiliate = Cache("Affiliate_" & intAffiliateID)
Else
myAffiliate = New Affiliate(intAffiliateID)
End If
The first thing that the code does is check if affiliate data caching is on. If it is, it checks if the Affiliate Object exists in the Cache Object for the affiliate with the specified id. If so, it just pulls the object out of the Cache Object and uses the data. If not it creates an instance of the class, using the affiliate’s id, and stores it in the Cache. As you can see, when the object is stored in the Cache, it is given an absolute expiration date using the Cache interval setting. If affiliate caching is turned off, an instance of the affiliate class is created and populated with data each time the page is loaded.
Some other things worth noting about the cache object….
You also have the option of setting a relative expiration date. If you use this option, the Cache Object will expire what you put in the Cache if it is not accessed for the amount of time you specify. Also, you can set priorities on the items you insert in the Cache and define functions that you want to be called when an item you insert in the Cache is removed. For more information, here is a link to the definition of the Cache Object’s insert method.
I have yet to produce performance numbers about how using the Cache performs versus not using the Cache. However, it is hard to imagine that using the Cache does not perform better than not using the Cache.
Posted at 07:11 PM | Permalink | Comments (2) | TrackBack (0)
The FileSystemWatcher control allows you to easily monitor a directory or set of directories. It raises events when files are added, deleted and updated and lets you perform actions cooresponding to those events.
At work, I have an application that allows users to upload image files to one of our web servers to be used on our web site. For the longest time now, someone has been manually copying those images to the rest of the servers on our web farm.
The first thing I know you are going to say is, "Do you know they have something called files replication?"
Let me just say...
1) I do know what file replication is.
2) It would have been a lot easier to use file replication to accomplish this.
However, I don't want to waste your time as to why the operations guys at my company wont use file replication. Hint...they deleted all the files off one of our servers once, and now they are scared of it. Oops, was that my outloud voice? :-o
I decided to create a service that would constantly monitor the one server and copy the new and updated files to the other servers. Honestly, the service only took me about 30 minutes to write, and that was with taking time to to figure out how to use the FileSystemWatcher control and remembering how to install and debug a service.
First I created a new C# Windows Service.
Next I created a configuration file for the service that had a setting for the source server and the targetservers. The contents of the file looked like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<sourceserver name="name of server to copy from" path="path on the server to monitor"/>
<targetserver name="name of server to copy files to" path="path on server to copy to"/>
</configuration>
You can set as many targetservers as you like.
After Visual Studio created the files for the project I only had to make a few edits to the code. First I had to add two private variables to the FileWatcher class:
private XmlDocument Config;Next I added this code when the service starts:
private System.Collections.Hashtable TargetServers;
private FileSystemWatcher FileWatcher;
this.FileWatcher.EnableRaisingEvents = true;Since I want to perform the same action when a file is changed or updated, I set the event handlers of both events to call the same function.
this.FileWatcher.Changed += new System.IO.FileSystemEventHandler(this.FileWatcher_Changed);
this.FileWatcher.Created += new System.IO.FileSystemEventHandler(this.FileWatcher_Changed);
After that, I updates the OnStart function to look like this:
protected override void OnStart(string[] args)Finally, I added the function to execute for the FileWatcher_Changed event:
{
Config = new XmlDocument();
TargetServers = new Hashtable();
string localpath = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase );
//load the config file
try
{
Config.Load(localpath+"\\config.xml");
}
catch (System.Xml.XmlException xex)
{
this.EventLog.WriteEntry("Could not open config file. Error was:\n"+xex.Message,System.Diagnostics.EventLogEntryType.Error,1,1);
}
//set the path that the filesystemwatcher will watch
FileWatcher.Path = Config.SelectSingleNode("configuration/sourceserver/@path").Value;
//fill the TargetServers Hashtable with all the target servers that we will copy the files to.
foreach (XmlNode node in Config.SelectNodes("configuration/targetserver"))
{
TargetServers.Add(node.SelectSingleNode("@name").Value,node.SelectSingleNode("@path").Value);
}
//set the file properties filesytemwatcher uses to detect changes to files
FileWatcher.NotifyFilter=NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.Size;
FileWatcher.IncludeSubdirectories=false;
}
private void FileWatcher_Changed(object sender, System.IO.FileSystemEventArgs e)The one last thing I needed to do was add the installer. Just right click on the designer for the services class files and select Create Installer. Save and build the Solution.
{
IDictionaryEnumerator ListEnumerator = TargetServers.GetEnumerator();
try
{
switch (e.ChangeType)
{
case WatcherChangeTypes.Created:
while (ListEnumerator.MoveNext())
{
File.Copy(e.FullPath, ListEnumerator.Value.ToString()+"\\"+e.Name, true);
}
break;
case WatcherChangeTypes.Changed:
while (ListEnumerator.MoveNext())
{
File.Copy(e.FullPath, ListEnumerator.Value.ToString()+"\\"+e.Name, true);
}
break;
}
}
catch (IOException ix)
{
this.EventLog.WriteEntry("IOException while copying files. Error was:\n"+ix.Message,System.Diagnostics.EventLogEntryType.Error,1,1);
}
catch (Exception x)
{
this.EventLog.WriteEntry("Unknown Exception while copying files. Error was:\n"+x.Message,System.Diagnostics.EventLogEntryType.Error,1,1);
}
}
To install the service, run the following in the directory where the exe for the service was created:
installutil filewatcher.exeYou can then start the service either in the Services Control Panel.
References I used while writing my code:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/vborireactingtofilesystemevents.asp
Posted at 11:49 PM | Permalink | Comments (21) | TrackBack (0)
Recently I discovered the wonders of the VBC.EXE command line compiler in the .Net Framework. It is fairly simple to use once you learn what the different command options do. There is a very good reference here.
I have a batch file set up that I run to do the compile. It does the following:
1) Backup the existing DLL.
2) Compile the new DLL.
3) Copy the new DLL to the target server.
This is the code for the batch file:
@echo off
echo Deleting Existing DLL
if exist "dlls\example.dll" del dlls\example.dll
echo Done Deleting DLL
set path=%path%;%SystemRoot%\Microsoft.net\Framework\v1.1.4322\;
echo Building example.dll
vbc.exe @response.rsp
echo Build Complete
echo Making Backup of DLL
if exist "target_server_dll_path\example.dll" xcopy /Y /R target_server_dll_path\example.dll backupdlls\ target_server_dll_path\example.dll
Echo Done Making Backup
Echo Copying DLL to Server
if exist "dlls\example.dll" xcopy /Y /R dlls\example.dll target_server_dll_path\example.dll
echo Done Copying DLL
Pause
Here is the .RSP file:
#add references for other DLLs that the project uses
/r:dlls\example2.dll
/r:dlls\example3.dll
/r:system.dll
/r:system.web.dll
/r:system.data.dll
/r:system.xml.dll
/imports:Microsoft.VisualBasic
/imports:System
/imports:System.Collections
/imports:System.Configuration
/imports:System.Data
/imports:System.Drawing
/imports:System.Web
/imports:System.Web.UI
/imports:System.Web.UI.WebControls
/imports:System.Web.UI.HTMLControls
/nologo
#debug is optional if you want to include debug info in your dll
#the app will run faster if you do not use the /debug option
/debug
#all my code behind files are in directory called codebehindfiles
/recurse:codebehindfiles\*.vb
#define the output file name
/out:dlls\example.dll
/target:library
/rootnamespace:whatever the root namespace of your project is
#/bugreport:bugreport.txt
In the first step I delete the existing dll. This prevents me from later on copying up the existing DLL to the target server if the compile fails. I then run vbc with the response.rsp file I created. After that I make a backup of the existing DLL on the target server I am about the copy the new DLL to and then I copy the new DLL to the target server. If there is a compile error, I uncomment the last line of the response file and it outputs all the comile errors to a file called bugreport.txt.
The PAUSE at the end of the batch file is useful for when you are too lazy to open cmd.exe. It allows you to run the batch file by double clicking on the file in explorer. If you did not have the PAUSE after it was all done the command window would disappear and you would not be able to see the output.
I keep all of these files on a network drive somewhere so someone else can copy .vb files to the codebehindfiles directory and run it if needed. This process works fairly well for me. The only problem I have had so far is that if someone besides me runs it, I get an error when they first run the all on the target server that the type global cannot be found. I believe this has something to do with permissions on the DLL. I will post an update to this when I figure out what the issue is with that.
References used when I was writing my own code:
http://www.flws.com.au/showusyourcode/codeLib/code/CompileSCut.asp?catID=5
http://support.microsoft.com/default.aspx?scid=kb;en-us;319976
http://p2p.wrox.com/archive/aspx_web_matrix/2002-07/3.asp
http://www.angryCoder.com/blog/entries/20030423.html
Posted at 11:03 AM | Permalink | Comments (3) | TrackBack (0)
Posted at 01:30 PM | Permalink | Comments (3) | TrackBack (0)
It is snowing in the DC Metro area. Well, not really snowing...A mix of rain, sleet and snow. The roads are fine, but people can't drive for shit around here when it rains. It is like their brains slow down when the roads are wet. I heard on the radio today that some salt was spilled on the highway and that everyone was rubber-necking to see what had happened. How stupid is that?!! Whenever I witness the following it just infuriates me:
1. Someone driving slow in the left lane. The left lane is a passing lane! If you get passed by several people on the right, it means you should move the f*ck over.
2. When people speed up when you try to pass them on the right.
3. People that stop in the middle of the road and get out of their car blocking the lane and then put on their flashers.
4. When people are passing an accident on the other side of the road and the slow down to look at the carnage.
5. People that don't pay attention at a toll and get stuck in the EZ-Pass lane when they don't have EZ-Pass. They then stop and hold everyone up while they try to cut into another toll lane.
Posted at 09:50 AM | Permalink | Comments (1) | TrackBack (0)
This is my first post and I have nothing very interesting to say except the following to give you an idea what this journal will be like:
1) I can't stand people that boycott Microsoft products
2) .Net rules
3) Managing people is harder than programming
4) Southpark is the greatest show on television
That is all for now. More to come when I have some more interesting things to talk about.
Posted at 10:49 PM | Permalink | Comments (0) | TrackBack (0)