怎么最大限度地降低多线程c#代码复杂性的示例分析

  介绍

小编给大家分享一下怎么最大限度地降低多线程c#代码复杂性的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!

分支或多线程编程是编程时最难最对的事情之一。这是由于它们的并行性质所致,即要求采用与使用单线程的线性编程完全不同的思维模式。对于这个问题,恰当类比就是抛接杂耍表演者,必须在空中抛接多个球,而不要让它们相互干扰。这是一项重大挑战。然而,通过正确的工具和思维模式,这项挑战是能应对的。

本文将深入介绍我为了简化多线程编程和避免争用条件,死锁等其他问题而编写的一些工具。可以说,工具链以语法糖和神奇委托为依据。不过,引用伟大的爵士音乐家迈尔斯·戴维斯的话:“在音乐中,没有声音比有声音更重要。”声音间断就产生了奇迹。

从另一个角度来说,不一定是关乎可以编码什么,而是关乎可以选择不编码什么,因为你希望通过间断代码行产生一点奇迹。引用比尔盖茨的一句话:“根据代码行数来衡量工作质量就像通过重量来衡量飞机质量一样。”因此,我希望能帮助开发人员减少编码量,而不是教导开发人员如何编写更多代码。

<强>同步挑战

在多线程编程方面遇到的第一个问题是,同步对共享资源的访问权限。当两个或多个线程共享对某个对象的访问权限且可能同时尝试修改此对象时,就会出现这个问题。当c#首次发布时,锁语句实现了一种基本方法,可确保只有一个线程能访问指定资源(如数据文件),且效果很好。C #中锁的关键字很容易理解,它独自颠覆了我们对这个问题的思考方式。

不过,简单的锁存在一个主要缺陷:它不区分只读访问权限和写入访问权限。例如,可能要从共享对象中读取10个不同的线程,并且通过系统。线程命名空间中的ReaderWriterLockSlim类授权这些线程同时访问实例,而不导致问题发生。与锁语句不同,此类可便于指定代码是将内容写入对象,还是只从对象读取内容。这样一来,多个读取器可以同时进入,但在其他所有读写线程均已完成自己的工作前,拒绝任何写入代码访问。

现在的问题是:如果使用ReaderWriterLock类,语法就会变得很麻烦,大量的重复代码既降低了可读性,又随时间变化增加了维护复杂性,并且代码中通常会分散有多个尝试和最后块。即使是简单的拼写错误,也可能会带来日后有时极难发现的灾难性影响。

通过将ReaderWriterLockSlim封装到简单的类中,这个问题瞬间解决,不仅重复代码不再会出现,而且还降低了小拼写错误毁一天劳动成果的风险。图1中的类完全基于λ技巧。可以说,这就是对一些委托应用的语法糖(假设存在几个接口)。最重要的是,它在很大程度上有助于实现避免重复代码原则(干燥)。

1:封装ReaderWriterLockSlim

public  class  Synchronizer, where  TImpl :, TIWrite, TIRead  {   ReaderWriterLockSlim 才能;_lock =, new  ReaderWriterLockSlim  ();   TImpl 才能;互联网;      public 才能;Synchronizer  (TImpl 共享),{   ,,,_shared =,共享;   ,,}      public 才能;void  Read  (Action

1中只有27行代码,但却精妙简洁地确保对象跨多个线程进行同步。此类假定类型中有读取接口和写入接口。如果由于某种原因而无法更改需要将访问权限同步到的基础类实现,也可以重复模板类本身三次,通过这种方式使用它。基本用法如2所示。

2:使用同步器类

interface  IReadFromShared  {   string 才能;GetValue  ();   }      interface  IWriteToShared  {   void 才能;SetValue  (string 价值);   }      class  MySharedClass : IReadFromShared, IWriteToShared  {   string 才能;_foo;      public 才能;string  GetValue  (), {   ,,,return  _foo;   ,,}      public 才能;void  SetValue  (string 价值),{   ,,,_foo =,价值;   ,,}   }      void  Foo  (Synchronizer

怎么最大限度地降低多线程c#代码复杂性的示例分析