我有一个 WCF 服务,我想在其中保存一个在服务运行时创建的 XML 列表,以便在服务关闭后保存,即在重新启动服务时查看它。调用 HTTP POST 时会将项目添加到列表中。但是,当程序中返回列表项的 HTTP GET 方法在重新启动服务后被调用时,它不会显示列表项,因为它们没有保存。我与此问题相关的问题是:
1) 如何保存列表以供将来参考?2)是否有某种机制可以在每次服务关闭时保存此列表,以便在重新启动服务时可以查看?
还有一个指针:我不希望将列表项保存为本地机器上的 xml 文件!
Tim 的建议是合理的,但是您不需要自定义服务主机来执行此操作。主要是将数据内容写入持久存储,在更新后的某个时间点。当您收到 POST 时,更新内存中的数据表示,然后将事物写入文件系统上的 xml 文件。
public void DoPost()
{
UpdateData();
SaveDataToFilesystem();
}
重新启动时,从文件中读取(如果存在)。
要处理并发,您必须在Update()
andSave()
方法中锁定数据。
如果系统负载很高,则将“写入文件文件系统”推迟到最多每 10 秒左右一次。
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;
}
}
对于真正的高并发性,您不希望在每个请求中都排队一个新的工作项。相反,您只需使用写入的专用线程。
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);
}
您还可以使用 AutoResetEvents 来通知编写器线程唤醒。