Reputation: 1
I have a WCF service in which I want to save an XML list which created while the service is running to also be saved once the service closes i.e. view it on restarting the service. Items are added to the list when HTTP POST is called. However when the HTTP GET method in the program that returns items of the list is called after restarting the service, it does not show the items of the list, since they are not saved. My questions related to this problem are:
1) How can the List be saved for future reference? 2) Is there some mechanism to save this list everytime the service closes, so that it can be viewed on restarting the service?
Just one more pointer: I do not wish to save the list items as xml files on my local machine !
Upvotes: 0
Views: 229
Reputation: 192637
Tim's suggestion is reasonable, however you do not need a custom service host to do it. The main thing is to write the content of the data into a persistent store, at some point after it's been updated. When you get a POST, update the in-memory data representation, then write the thing to an xml file on the filesystem.
public void DoPost()
{
UpdateData();
SaveDataToFilesystem();
}
When you restart, read from the file if it exists.
To handle concurrency, you will have to lock the data in the Update()
and Save()
methods.
If there is a high load on the system, then defer the "write to the file filesystem" to at most once every 10 seconds or so.
public void DoPost()
{
UpdateData();
QueueWriteToFilesystem();
}
private MyInternalDataType data;
private DateTime lastWrite = new DateTime(1970,1,1); // init value
private void QueueWriteToFilesystem()
{
ThreadPool.QueueUserWorkItem( MaybeWrite );
}
private int delayInMilliseconds = 1000 * 10; // 10 seconds
private void MaybeWrite()
{
System.Threading.Thread.Sleep(delayInMilliseconds);
lock (data)
{
var delta = System.DateTime.Now - lastWrite;
if (delta < new System.TimeSpan(0, 0, 0, 0, delayInMilliseconds))
{
// less than 10s since last write
// do nothing
return;
}
ActuallySaveToFilesystem();
lastWrite = System.DateTime.Now;
}
}
For really high concurrency, you wouldn't want to queue a new workitem with every request. You'd instead just use a dedicated thread that writes.
public void DoPost()
{
UpdateData();
lastUpdate = System.DateTime.Now;
}
private void DedicatedWriter()
{
do
{
System.Threading.Thread.Sleep(delayInMilliseconds);
lock (data)
{
var delta = lastUpdate - lastWrite;
if (delta < new System.TimeSpan(0, 0, 0, 0, 200))
{
// small amount of time since prior write;
// do nothing
return;
}
ActuallySaveToFilesystem();
lastWrite = System.DateTime.Now;
}
} while (true);
}
You could also use AutoResetEvents to signal the writer thread to wake up.
Upvotes: 1