InvalidOperationException - 对象当前正在其他地方使用

cla*_*aws 26 .net c# backgroundworker winforms

我已经完成了这个问题,但没有帮助.

这里的情况不同.我正在使用Backgroundworkers.第一个backgroundworker开始操作用户的图像输入和firstbackgroundworker_runworkercompleted()我正在使用调用其他3个后台工作者

 algo1backgroundworker.RunWorkerAsync();
 algo2backgroundworker.RunWorkerAsync();
 algo3backgroundworker.RunWorkerAsync();
Run Code Online (Sandbox Code Playgroud)

这是每个的代码:

algo1backgroundworker_DoWork()
{
 Image img = this.picturebox.Image;
 imgclone = img.clone();
 //operate on imgclone and output it
}

algo2backgroundworker_DoWork()
{
 Image img = this.picturebox.Image;
 imgclone = img.clone();
 //operate on imgclone and output it
}
Run Code Online (Sandbox Code Playgroud)

类似的操作在其他algo*backgrougrondworker_doWork()中完成.

现在有时我得到"InvalidOperationException - 对象目前正在其他地方使用".它很随意.我有时会在algo1backgroundworker_DoWork中获取此信息,有时在algo2backgroundworker_DoWork中,有时在Application.Run(new myWindowsForm())中获取;

我不知道发生了什么事.

Han*_*ant 50

GDI +中有一个锁,可以防止两个线程同时访问位图.这不是一种阻塞的锁,它是"程序员做错了什么,我会抛出异常"的那种锁.您的线程正在轰炸,因为您正在克隆所有线程中的图像(==访问位图).你的UI线程是轰炸,因为它试图在线程克隆它的同时绘制位图(==访问位图).

您需要将位图的访问权限限制为仅一个线程.在启动BGW之前克隆UI线程中的图像,每个BGW都需要自己的图像副本.在RunWorkerCompleted事件中更新PB的Image属性.你会以这种方式失去一些并发性但这是不可避免的.


Jer*_*Gee 23

因此,看起来您的BackgroundWorkers正在尝试同时访问相同的Windows窗体组件.这可以解释为什么失败是随机的.

你需要确保使用a不会发生这种情况lock,或许是这样:

private object lockObject = new object();

algo1backgroundworker_DoWork()
{
    Image imgclone;
    lock (lockObject)
    {
        Image img = this.picturebox.Image;
        imgclone = img.clone();
    }

    //operate on imgclone and output it
}
Run Code Online (Sandbox Code Playgroud)

请注意,我确保imgclone是此方法的本地方法 - 您绝对不希望在所有方法中共享它!

另一方面,所有方法都使用相同的lockObject实例.当BackgroundWorker方法进入其lock{}部分时,到达该点的其他人将被阻止.因此,确保锁定部分中的代码快速非常重要.

当您"输出"已处理的图像时,请务必小心以确保不对UI进行跨线程更新.检查这篇文章是否有一个简洁的方法来避免这种情况.


DW.*_*DW. 5

在 Windows 窗体中,您不仅应该只从单个线程访问控件,而且该线程应该是主应用程序线程,即创建控件的线程。

这意味着在 DoWork 中您不应访问任何控件(不使用 Control.Invoke)。因此,在这里您将调用 RunWorkerAsync 传入您的图像克隆。在 DoWork 事件处理程序中,您可以从 DoWorkEventArgs.Argument 中提取参数。

只有 ProgressChanged 和 RunWorkerCompleted 事件处理程序应与 GUI 交互。