8

我正在编写一个具有分层通信接口的应用程序。
这样做是为了从应用程序的用户界面部分抽象通信,并使其更具可扩展性/可维护性。
例如:

替代文字

将上图中的每个框视为一个单独的类。
通用通信接口填充描述交易数据和通信“健康”的字符串变量,这些变量又通过一系列公共函数调用复制到应用程序。例如,应用程序会调用 App-Sub-System:

class Application
{
   private void SomeUpdateFunction()
   {
      this.textBox1.AppendText(this.AppSubSystem.GetText());
   }
}

class AppSubSystem
{
   public string GetText()
   {
      return this.GenericCommsInterface.GetText();
   }
}

class GenericCommsInterface
{
   public string GetText()
   {
      string sRetVal = this.sText; // sText is populated by other functions in the class.
      this.sText = null; // Suspected race condition is here.
      return sRetVal;
   }
}

sText由类中的其他函数异步填充。我相信在和下一行
之间发生了竞争情况。 有人可以建议一种避免或防止这种竞争状况的方法吗?会使用帮助,还是我应该这样做的另一种方式?string sRetVal = this.sText;this.sText = null;
StringBuilder

4

3 回答 3

4

您可能应该在您想要触摸的任何时候获取锁定this.sText- 在更新它的功能以及您的GetText功能中。这将确保一次只有一个线程在搞乱它,因为(假设您的线程有锁)其他线程将坐下来等待,直到当前线程完成。

我建议您使用 StringBuilder,部分是为了简化锁定,因为锁定恰好被拘留的字符串,或者在锁定操作中间切换的字符串(从局外人的角度来看,因此解锁)可能会导致真正的坏魔力. 这样的事情会有所帮助:

lock (this.sbText)
{
    sRetVal = this.sbText.ToString();
    this.sbText.Length = 0;
}

或者,您可以 lock on this,但这很难看——你的锁应该在里面,尽可能私有,以避免奇怪的副作用(比如如果其他对象试图获取这个对象的锁——它不能t 在sbText被修改时这样做)。

于 2010-07-21T21:33:47.213 回答
1
public string GetText()
{
   lock( someObject )
   {
      string sRetVal = this.sText; // sText is populated by other functions in the class.
      this.sText = null; // Suspected race condition is here.
      return sRetVal;
   }
}    

在你的集合中

lock( someObject )
{
    //...
    this.sText = value;
}
于 2010-07-21T21:33:00.583 回答
1

由于您没有保护 sText,因此此代码肯定不会在线程环境中工作。您需要锁定所有访问它的人。

于 2010-07-21T21:33:14.593 回答