This is pretty trick because you need to closely monitor the ThreadPool and it will require a form of synchronization. Here's a quick and dirty example of a way to do this.
class XmlManager {
private object m_lock = new object();
private HashSet<string> m_inPool = new HashSet<string>();
private void Run(object state) {
string name = (string)state;
try {
FunctionThatActuallyProcessesFiles(name);
} finally {
lock ( m_lock ) { m_inPool.Remove(name); }
}
}
public void MaybeRun(string xmlName) {
lock ( m_lock ) {
if (!m_pool.Add(xmlName)) {
return;
}
}
ThreadPool.QueueUserWorkItem(Run, xmlName);
}
}
This is not a foolproof solution. There is at least one race condition in the code. Namely that an item could be being removed from the pool while you're trying to add it back in and it won't actually get added. But if your are only concerned with them being processed a single time, this doesn't matter.