【问题标题】:Accessing an object on 2 threads at the same time同时访问2个线程上的对象
【发布时间】:2011-05-07 09:14:17
【问题描述】:

我有一个拥有 2 个线程的 c# 应用程序。一个线程正在创建一个对象,而第二个线程正在使用同一个对象。大多数时候它工作正常,但有时它会给出错误Object is in use currently elsewhere.

如何让线程可以同时使用对象?

谢谢

编辑

我正在访问一个Bitmap 对象。一个线程从流中创建此位图,将其显示在PictureBox 上,第二个线程再次将此Bitmap 转换为Byte 并在网络上传输它。

【问题讨论】:

  • 添加一些代码并告诉我们对象是什么类型。
  • "对象当前正在其他地方使用。"听起来不像是标准的 .NET 异常——你到底在做什么?任何特定的图书馆?请注意,对象需要仔细编写才能线程安全;目前尚不清楚您的对象是否线程安全的,或者只是被折磨

标签: c# multithreading thread-safety


【解决方案1】:

您的基本方法是锁定对象(与共享对象处于 1-1 关系)和 lock 语句:

MyObject shared = ...;
object locker = new object();

// thread A
lock(locker)
{
  // use 'shared'
}

// thread B
lock(locker)
{
  // use 'shared'
}

编辑后

如果您以任何方式转换位图,最好忘记并行。这是一个复杂的类,有自己的内部锁定。

如果您不转换,则不要使用位图。为 PictureBox 和传出流分叉传入流将更容易(并非微不足道)。

【讨论】:

    【解决方案2】:

    错误消息的语言使它听起来像是来自 GDI 子系统或类似的东西。这是一个 GUI 应用程序吗?如果是,最可能的原因是您正在从“非 GUI”线程访问 GUI 元素。对于初学者来说,任何 GUI 控件上的所有操作,如表单或按钮,都必须通过它的消息泵发送给它。你可以通过粗略地做到这一点

    if (form.InvokeRequired)
    {
        form.BeginInvoke( your operation method);
    } 
    else
    { 
        (same operation method);
    } 
    

    【讨论】:

      【解决方案3】:

      我正在访问一个位图对象。一个线程从流中创建此位图,将其显示在 PictureBox 上,第二个线程再次将此位图转换为字节并在网络上传输

      从多个线程访问Bitmap 对象不会导致InvalidOperationException。如果您同时写入和读取同一个实例,它可能会破坏您的数据,但据我所知Bitmap 并没有强加特定的线程模型。另一方面,PictureBox 确实如此,所以我怀疑您正在尝试从非 GUI 工作线程读取或写回 PictureBox 实例。

      【讨论】:

      • 是的!我正在访问PictureBox 发送位图。
      • 好吧,你不能这样做。使用一些默认的异步模式来避免这种情况。一些要查找的关键字:SynchronizationContextAPM
      【解决方案4】:

      你需要lock这个变量每次被任一线程使用。

      这样:

      object mylock;
      
      lock(mylock)
      {
      //do someething with object
      }//lock scope finishes here
      

      其中mylock 由访问此特定变量的每个锁使用。

      【讨论】:

      • 学究:你不会锁定一个变量;您锁定一个 object,通常存储在 field 中。但在我们看到更多上下文之前,对我来说这不是正确的方法……
      猜你喜欢
      • 1970-01-01
      • 2013-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多