Это довольно хитрый трюк, потому что вам нужно внимательно следить за ThreadPool, и для этого потребуется форма синхронизации. Вот быстрый и грязный пример того, как это сделать.
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);
}
}
Это не надежное решение. В коде есть хотя бы одно условие гонки. А именно, что элемент может быть удален из пула, пока вы пытаетесь добавить его обратно, и он фактически не будет добавлен. Но если вы заинтересованы только в том, чтобы они обрабатывались один раз, это не имеет значения.