对单例类的多线程访问

时间:2014-11-19 22:16:17

标签: c# multithreading singleton

我很难绕过访问具有多个线程的单例类。

这篇文章给了我一个很好的起点,让我的单例线程安全: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)在ProcessFile中,我将文件添加到字典中并开始处理。

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唯一标识(即没有文件会遭受多次访问),我可以保留这种方法,还是我仍然需要& #34;锁&#34;我的方法?

1 个答案:

答案 0 :(得分:0)

是的,只要您只读共享字典,一切都应该没问题。并且您可以并行处理文件,只要它们是不同的文件,正如您正确提到的那样。

The documentation解释说:

  

只要未修改集合,Dictionary<TKey, TValue>可以同时支持多个阅读器。

因此,如果有人可以拨打AddFileForProcessing(没有锁定),你就无法并行做任何事情。但只有WriteProcessResultToProperFile的电话,一切都会好的。这意味着如果你想并行调用AddFileForProcessing,那么你需要锁定两个方法(事实上:将触及这个字典的所有代码部分)。