Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单例类的多线程访问_C#_Multithreading_Singleton - Fatal编程技术网

C# 单例类的多线程访问

C# 单例类的多线程访问,c#,multithreading,singleton,C#,Multithreading,Singleton,我很难集中精力访问一个包含多个线程的单例类 本文为我提供了一个很好的起点,使我的单例线程安全: 我的singleton类应该将一组文件视为单个数据单元,但以并行方式处理它们 我将每个文件的信息存储在一个字典中,并向调用线程返回一个唯一的密钥,该密钥将使用日期时间和随机数创建,以便每个线程稍后可以引用自己的文件 public string AddFileForProcessing(FileForProcessing file) { var id = CreateUniqueFileId()

我很难集中精力访问一个包含多个线程的单例类

本文为我提供了一个很好的起点,使我的单例线程安全:

我的singleton类应该将一组文件视为单个数据单元,但以并行方式处理它们


我将每个文件的信息存储在一个字典中,并向调用线程返回一个唯一的密钥,该密钥将使用日期时间和随机数创建,以便每个线程稍后可以引用自己的文件

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的创建事件并创建调用AddFileForProcessing的线程:

public void ProcessIncomingFile(object sender, EventArgs e)
{
    var file = ((FileProcessingEventArg)e).File;
    ThreadPool.QueueUserWorkItem(
    item =>
    {
        ProcessFile(file);
    });
}
在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,并使用不同的参数writeProcessResultTopropertFile。这会让他们打两个不同的电话吗


由于它将在一个文件上运行,该文件将由属于单个线程的id唯一标识,即没有文件会遭受多次访问,我可以保持此方法不变,还是仍然必须锁定我的方法?

是的,只要您只从共享字典中读取,一切都应该正常。正如您正确提到的,只要文件是不同的文件,您就可以并行处理这些文件

说明:

只要不修改集合,词典可以同时支持多个读取器


所以,如果有人可以调用AddFileForProcessing而不使用锁,那么您无法并行执行任何操作。但是,如果只调用WriteProcessResultTopropertFile,就可以了。这意味着,如果要并行调用AddFileForProcessing,那么实际上两种方法都需要锁:所有与此字典相关的代码部分。

此方法使用的实例数据是什么?如果_files不是一个安全的集合,则必须对其使用锁。关键是,如何确保每个线程使用不同的参数进行调用。1._文件是由单个线程填充的,还是由多个线程填充的?2._文件是否仅在启动执行处理的线程之前填充?3.如何确保每个处理线程从_文件中选择唯一的id。我将每个文件的信息存储在一个字典中,并向调用线程返回一个唯一的密钥,以便每个线程以后可以引用自己的文件。在singleton类实例所在线程中的初始化过程中?换句话说。。文件集合在运行时会更改吗?