RE: Web Service Startup
-
I've just started to learn C# and am trying to use it to create a web service, and I have a question that I hope can be answered. I have a set of instructions to be run before each instance of the service is started. What I'm trying to do is put some information from a file into memory and then the service will find the information it needs and return that to the user. I currently have it working where it reads the files from disk every time a request is received, but that seems horribly inefficient, and was wondering if there was a way to have this done once? Thanks for your help
-
I've just started to learn C# and am trying to use it to create a web service, and I have a question that I hope can be answered. I have a set of instructions to be run before each instance of the service is started. What I'm trying to do is put some information from a file into memory and then the service will find the information it needs and return that to the user. I currently have it working where it reads the files from disk every time a request is received, but that seems horribly inefficient, and was wondering if there was a way to have this done once? Thanks for your help
-
-
I've just started to learn C# and am trying to use it to create a web service, and I have a question that I hope can be answered. I have a set of instructions to be run before each instance of the service is started. What I'm trying to do is put some information from a file into memory and then the service will find the information it needs and return that to the user. I currently have it working where it reads the files from disk every time a request is received, but that seems horribly inefficient, and was wondering if there was a way to have this done once? Thanks for your help
Your question is not clear as you use "each instance" and yet you seem to want to have a global value. If what you are trying to accomplish is to save yourself from having to re-read a semi-static file, here is what I would try... // THE RESULTANT DATA object myData = null; // THE NAME OF THE FILE string myFileName = @Server.MapPath(@"\dir\filename"); // GET THE INFO System.IO.FileInfo fileInfo = new System.IO.FileInfo(myFileName); // DOES IT EXIST if (fileInfo.Exists) { // THE NAME OF THE DATA KEY string myDataKey = "DATA"; // THE NAME OF THE TIMESTAMP KEY string myTimestampKey = "DATETIME"; // GET THE PREVIOUS TIME STAMP (IF ANY, ELSE A NULL) DateTime myTimestamp = Application[myTimestampKey] as DateTime; // GET THE TIMESTAMP DateTime currentTimestamp = fileInfo.LastWriteTime; // GET THE PREVIOUS DATA (IF ANY, ELSE A NULL) myData = Application[myKey]; // ANY PREVIOUS DATA? if (myData != null) { // DO WE HAVE A TIMESTAMP? if (myTimestamp == null) { // SHOULD NOT HAPPEN, BUT JUST IN CASE (DATA AND NO TIMESTAMP) myData = null; } else { // SAME? if (!myTimestamp.Equals(currentTimestamp)) { // FILE CHANGED, RE-READ myData = null; } } } // ALREADY THERE? if (myData == null) { // GET THE DATA myData = ...; // AND SAVE FOR NEXT TIME Application[myDataKey] = myData; // AND SAVE THE TIMESTAMP Application[myTimestampKey] = currentTimestamp; } } Have fun.....
-
Thanks for the help. However, I'm really new and have another question. Where would I put the CacheDependency?
Because you must check the cache each time you get the item from it, you'd want to encapsulate this in a method that the constructor (called when the Web Service class is instantiated) and your methods can call to get the object from the cache:
[WebService]
public class MyWebService : WebService
{
public MyWebService()
{
// Initialize to boost performance of first call.
GetContent();
}
[WebMethod]
public void DoSomething()
{
string content = GetContent();
if (content != null)
// do something with the content of the file that's cached.
}
private string GetContent()
{
string content = (string)Context.Cache[CacheName];
if (content == null)
{
string path = Server.MapPath("/path/to/virtual/file.txt");
using (StreamReader reader = new StreamReader(path))
{
content = reader.ReadToEnd();
reader.Close();
}
Context.Cache.Add(
CacheName,
content,
new CacheDependency(path),
Cache.NoAbsoluteExpiration,
Cache.NoSlidingExpiration,
CacheItemPriority.Default,
null);
}
return content;
}
private const string CacheName = "CONTENT";
}This places the content of a file in the cache. The
CacheDependency
makes sure that if the file is changed, the cache item is invalidated. This means thatnull
would be returned when trying to get the item from the cache. In this case, you read-in the content of that file and re-add it to the cache.Microsoft MVP, Visual C# My Articles
-
Your question is not clear as you use "each instance" and yet you seem to want to have a global value. If what you are trying to accomplish is to save yourself from having to re-read a semi-static file, here is what I would try... // THE RESULTANT DATA object myData = null; // THE NAME OF THE FILE string myFileName = @Server.MapPath(@"\dir\filename"); // GET THE INFO System.IO.FileInfo fileInfo = new System.IO.FileInfo(myFileName); // DOES IT EXIST if (fileInfo.Exists) { // THE NAME OF THE DATA KEY string myDataKey = "DATA"; // THE NAME OF THE TIMESTAMP KEY string myTimestampKey = "DATETIME"; // GET THE PREVIOUS TIME STAMP (IF ANY, ELSE A NULL) DateTime myTimestamp = Application[myTimestampKey] as DateTime; // GET THE TIMESTAMP DateTime currentTimestamp = fileInfo.LastWriteTime; // GET THE PREVIOUS DATA (IF ANY, ELSE A NULL) myData = Application[myKey]; // ANY PREVIOUS DATA? if (myData != null) { // DO WE HAVE A TIMESTAMP? if (myTimestamp == null) { // SHOULD NOT HAPPEN, BUT JUST IN CASE (DATA AND NO TIMESTAMP) myData = null; } else { // SAME? if (!myTimestamp.Equals(currentTimestamp)) { // FILE CHANGED, RE-READ myData = null; } } } // ALREADY THERE? if (myData == null) { // GET THE DATA myData = ...; // AND SAVE FOR NEXT TIME Application[myDataKey] = myData; // AND SAVE THE TIMESTAMP Application[myTimestampKey] = currentTimestamp; } } Have fun.....
Sorry for the confusion. What I want is a global value. I think I understand your example (thank you), however, I'm not sure where to put it in my code. The only place I can see to add it would be in the constructor, but I'm not sure if this would cause this code to be run each time the service received a request (I think it would). If I understand everything correctly, then if I put your example in the constructor, then the first time the service handled a request (or when the file was changed) it would get the data, other wise is would skip the step to load the data. Is that right? Thanks for your help!
-
Your question is not clear as you use "each instance" and yet you seem to want to have a global value. If what you are trying to accomplish is to save yourself from having to re-read a semi-static file, here is what I would try... // THE RESULTANT DATA object myData = null; // THE NAME OF THE FILE string myFileName = @Server.MapPath(@"\dir\filename"); // GET THE INFO System.IO.FileInfo fileInfo = new System.IO.FileInfo(myFileName); // DOES IT EXIST if (fileInfo.Exists) { // THE NAME OF THE DATA KEY string myDataKey = "DATA"; // THE NAME OF THE TIMESTAMP KEY string myTimestampKey = "DATETIME"; // GET THE PREVIOUS TIME STAMP (IF ANY, ELSE A NULL) DateTime myTimestamp = Application[myTimestampKey] as DateTime; // GET THE TIMESTAMP DateTime currentTimestamp = fileInfo.LastWriteTime; // GET THE PREVIOUS DATA (IF ANY, ELSE A NULL) myData = Application[myKey]; // ANY PREVIOUS DATA? if (myData != null) { // DO WE HAVE A TIMESTAMP? if (myTimestamp == null) { // SHOULD NOT HAPPEN, BUT JUST IN CASE (DATA AND NO TIMESTAMP) myData = null; } else { // SAME? if (!myTimestamp.Equals(currentTimestamp)) { // FILE CHANGED, RE-READ myData = null; } } } // ALREADY THERE? if (myData == null) { // GET THE DATA myData = ...; // AND SAVE FOR NEXT TIME Application[myDataKey] = myData; // AND SAVE THE TIMESTAMP Application[myTimestampKey] = currentTimestamp; } } Have fun.....
When I try this: DateTime tpmTimestamp = Application[tpmTimestampKey] as DateTime; the compiler tells me "The as operator must be used with a reference type ('System.DateTime' is a value type). I'm sorry if this seems really trivial, but I'm just learning C# I've found a way to fix this: if(Application[tpmTimestampKey] == null) tpmTimestamp = CurrentTime; else tpmTimestamp = (DateTime)Application[tpmTimestampKey]; Thanks for your help!