对单例类的多线程访问
本文关键字:访问 多线程 单例类 | 更新日期: 2023-09-27 18:31:17
我很难理解访问具有多个线程的单例类。
这篇文章为我提供了一个很好的起点,让我的单例线程安全:http://csharpindepth.com/Articles/General/Singleton.aspx
我的单例类应该将一组文件视为单个数据单元,但以并行方式处理它们。
我将每个文件的信息存储在字典中,并将唯一键(将使用 DateTime 和随机数创建)返回给调用线程,以便每个线程以后可以引用自己的文件。
public string AddFileForProcessing(FileForProcessing file)
{
var id = CreateUniqueFileId();
var resultFile = CreateResultFileFor(file);
//These collections are written here and only read elsewhere
_files.Add(id, file);
_results.Add(id, resultFile)
return id;
}
然后稍后线程调用传递此 id 的方法。
public void WriteProcessResultToProperFile(string id, string[] processingResult)
{
//locate the proper file in dictionary using id and then write information...
File.AppendAllLines(_results[key].FileName, processingResult);
}
这些方法将在类中访问,该类:
a) 响应 FileWatcher 的 Created 事件并创建调用 AddFileForProcessing 的线程:
public void ProcessIncomingFile(object sender, EventArgs e)
{
var file = ((FileProcessingEventArg)e).File;
ThreadPool.QueueUserWorkItem(
item =>
{
ProcessFile(file);
});
}
b) 在进程文件中,我将文件添加到字典中并开始处理。
private void ProcessFile(FileForProcessing file)
{
var key = filesManager.AddFileForProcessing(file);
var records = filesManager.GetRecordsCollection(key);
for (var i = 0; i < records.Count; i++)
{
//Do my processing here
filesManager.WriteProcessResultToProperFile(key, processingResult);
}
}
现在我不明白当两个线程调用这些方法时会发生什么,因为它们都使用相同的实例。
每个线程将使用不同的参数调用 AddFileForProcessing 和 WriteProcessResultToProperFile。这是否使他们成为两个不同的电话?
由于它将对一个文件进行操作,该文件将由属于单个线程的 id 唯一标识(即没有文件会遭受多次访问),我可以保持此方法不变还是仍然必须"锁定"我的方法?
是的,只要您只从共享字典中阅读,一切都应该没问题。正如您正确提到的,只要它们是不同的文件,您就可以并行处理这些文件。
该文档解释:
只要不修改集合,
Dictionary<TKey, TValue>
就可以同时支持多个读取器。
因此,如果任何人都可以调用AddFileForProcessing
(没有锁定),则无法并行执行任何操作。但是只打电话给WriteProcessResultToProperFile
,那就没事了。这意味着如果你想并行调用AddFileForProcessing
,那么你在两个方法中都需要锁(实际上:将接触这个字典的所有代码部分)。