2

我工作的数据大部分是读取数据,我希望尽可能高效地执行这些工作,并且我需要提供线程安全访问。我如何优化阅读权限?

我是C#和线程的初学者,所以对我的问题的任何解释都会受到欢迎。由于

回答

2

我发现在C#6食谱

使用ReaderWriterLockSlim这个答案让与升级,从读锁写能力多读/单写访问。举个例子,假设开发者正在开始一个新项目。不幸的是,该项目人员不足,因此开发人员必须对团队中其他人员的任务作出响应。每个其他团队成员还会要求开发人员对其任务进行状态更新,有些人甚至可以更改开发人员分配的任务的优先级。开发人员通过AddTask方法分配任务。为了保护我们用ReaderWriterLockSlim写锁的开发任务集合,呼吁EnterWrite锁定当添加到DeveloperTasks收集任务和ExitWriteLock加入完成时:

public void AddTask(DeveloperTask newTask) 
    { 
     try 
     { 
      Lock.EnterWriteLock();   
      // if we already have this task (unique by name)   
      // then just accept the add as sometimes people   
      // give you the same task more than once :)   
      var taskQuery = from t in DeveloperTasks 
          where t == newTask 
          select t; 
      if (taskQuery.Count<DeveloperTask>() == 0) 
      { 
       Console.WriteLine($"Task {newTask.Name} was added to developer"); 
       DeveloperTasks.Add(newTask); 
      } 
     } 
     finally 
     { 
      Lock.ExitWriteLock(); 
     } 
    } 

当一个项目团队成员需要了解的任务的状态,他们所谓的IsTaskDone方法,它通过调用EnterReadLock和ExitReadLock使用的ReaderWriterLockSlim读锁:

 public bool IsTaskDone(string taskName) 
    { 
     try 
     { 
      Lock.EnterReadLock(); 
      var taskQuery = from t in DeveloperTasks 
          where t.Name == taskName select t; 
      if (taskQuery.Count<DeveloperTask>() > 0) 
      { 
       DeveloperTask task = taskQuery.First<DeveloperTask>(); 
       Console.WriteLine($"Task {task.Name} status was reported."); 
       return task.Status; } } 
     finally 
     { 
      Lock.ExitReadLock(); 
     } 
     return false; 
    } 

有团队的某些管理成员谁必须增加的优先权的权利他们分配给开发人员的任务。他们通过调用Developer上的IncreasePriority方法来实现这一点。 IncreasePriority使用ReaderWriterLockSlim上的可升级锁定,方法是首先调用EnterUpgradeable Lock方法获取读取锁定,然后如果任务位于队列中,则升级到写入锁定以调整任务的优先级。一旦优先级调整, 写锁被释放,这降低了回锁的读锁,该锁通过调用释放ExitUpgradeableReadLock:

public void IncreasePriority(string taskName) 
    { 
     try 
     { 
      Lock.EnterUpgradeableReadLock(); 
      var taskQuery = from t in DeveloperTasks 
          where t.Name == taskName select t; 
      if (taskQuery.Count<DeveloperTask>() > 0) 
      { DeveloperTask task = taskQuery.First<DeveloperTask>(); 
       Lock.EnterWriteLock(); task.Priority++; 
       Console.WriteLine($"Task {task.Name}" + $" priority was increased to {task.Priority}" + " for developer"); Lock.ExitWriteLock(); 
      } 
     } 
     finally 
     { 
      Lock.ExitUpgradeableReadLock(); 
     } 
    } 

讨论的ReaderWriterLockSlim是为了取代现有的ReaderWriterLock有以下几个原因:•ReaderWriterLock比使用Monitor要慢五倍以上。 ReaderWriterLock的递归语义不是标准的,并且在某些线程重入情况下被破坏。 ReaderWriterLock中的升级锁定方法是非原子的。虽然ReaderWriterLockSlim只比Monitor大约慢两倍,但它更灵活并优先执行写操作,因此在“少写,多读”情况下,它比Monitor更具可扩展性。还有一些方法可以确定持有哪种类型的锁以及有多少线程正在等待获取它。默认情况下,锁定获取递归是不允许的。如果你两次调用EnterReadLock,你会得到一个LockRecursionException。您可以通过将Lock RecusionPolicy.SupportsRecursion枚举值传递给接受它的ReaderWriterLockSlim的构造函数重载来启用锁定递归。尽管可以启用递归锁定,但它通常是不鼓励的,因为它会使问题变得复杂,并产生调试无趣的问题。

0

所以,如果你想读线程安全的,你可以使用“锁声明线程内上要确保串行访问的资源创建一个线程

// 
Threat t = new Thread (My_Function); 
// or 
Thread t = new Thread (()=> 
{ 
    //your code here 
}); 
t.start(); 

的基础

lock (Read_resource_object) 
{ 
} 

什么锁确实是,是第一次代码运行在锁声明将“锁定”资源,直到再花括号,这并不妨碍其他代码访问该对象,相反,如果有的话其他代码会调用该资源上的一个锁,即代码块直到锁定它的当前线程解锁它。当然要非常小心,以确保你没有得到一个线程锁,这通常发生在第一次锁内部时,代码流会以某种方式导致尝试在解锁之前锁定相同的代码。除此之外,我会建议阅读一些教程,因为多线程和线程安全是困难和复杂的!

查找任务以及它们包装线程并提供附加功能。