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进行跨线程更新.检查这篇文章是否有一个简洁的方法来避免这种情况.
在 Windows 窗体中,您不仅应该只从单个线程访问控件,而且该线程应该是主应用程序线程,即创建控件的线程。
这意味着在 DoWork 中您不应访问任何控件(不使用 Control.Invoke)。因此,在这里您将调用 RunWorkerAsync 传入您的图像克隆。在 DoWork 事件处理程序中,您可以从 DoWorkEventArgs.Argument 中提取参数。
只有 ProgressChanged 和 RunWorkerCompleted 事件处理程序应与 GUI 交互。
归档时间: |
|
查看次数: |
30737 次 |
最近记录: |