【发布时间】:2015-03-04 09:18:17
【问题描述】:
我试图在 GTk# 中使用 system.drawing 来操作图像。我希望 UI 在用户更新文本框后立即更新屏幕上的图像。为了实现这一点,我尝试使用 winforms 中的后台工作人员,它起作用了但是当文本框以更高的速度更新时,应用程序就会卡住而没有错误。
所以我在这里查看了 GTK 中的多线程 http://www.mono-project.com/docs/gui/gtksharp/responsive-applications/ 并创建了一个线程。
void textboxchanged()
{
Thread thr = new Thread (new ThreadStart (ThreadRoutine));
thr.Start ();
}
static void ThreadRoutine ()
{
LargeComputation ();
}
static void LargeComputation ()
{
image=new Bitmap(backupimage);
//Long image processing
}
当文本框中的输入速度甚至有点快时,它的效果比后台工作人员在其他地方抛出当前正在使用的对象错误image=new Bitmap(backupimage); 效果差。我做错了什么?
更新 1:
我没有使用同时执行 2 个不同操作的 2 个不同线程处理同一图像。我在旧线程完成之前调用执行相同操作的线程。在后台工作人员中,我需要一种方法来检查是否旧线程在启动新线程之前已经完成工作。所以基本上我正在寻找的是一种检查同一线程实例是否存在的方法
正在运行。在 winforms 中我曾经做过if(backgroundworker.isbusy==false) then do stuff
更新 2
性能下降的解决方案
正如@voo 所建议的,替换全局位图有助于解决问题。我所做的不是使用全局位图。我创建了一个全局字符串(文件名)。现在我使用img=new Bitmap(filename)。尝试快速执行,因为我不能出现错误。所以为了更新 GUI,我使用了这里建议的调用mono-project.com/docs/gui/gtksharp/responsive-applications/。事情是没有错误出现并且图像得到更新,但是当打字操作足够快时,就会涉及到等待。性能下降了。后台工作人员不是这种情况。有没有办法提高性能。
在大图处理操作方法的最后我添加了这个来更新GUI
Gtk.Application.Invoke (delegate {
MemoryStream istream=new MemoryStream();
img.Save (istream, System.Drawing.Imaging.ImageFormat.Png);
istream.Position = 0;
workimagepixbuff = new Gdk.Pixbuf (istream);
image1.Pixbuf = workimagepixbuff.ScaleSimple (400, 300, Gdk.InterpType.Bilinear);
});
// cannot directly convert Bitmap to Pixbuff,so doing this
【问题讨论】:
-
我将使用我的水晶球(因为根本不知道 gtk)并说 gtk 就像几乎所有其他 UI 工具包一样不喜欢你从主线程以外的线程更新 GUI线程并提供一些方法来在主线程街道上对操作进行排队,从而完成昂贵的计算。
-
@Voo 我没有在线程中更新 UI。我只是在处理图像。
-
你能给使用确切的例外吗?我只是对 libgdiplus 和 mono 源进行了 grep-ped,但我找不到对您提供的文本的任何引用。还是您在 Windows 上运行?
-
@fog 我在 Windows 上运行。例外是系统异常-对象当前在其他地方使用,我明天将更新确切的详细信息,我现在无法访问电脑。我认为是System.InvalidOperationException
-
你是否从多个线程访问同一个图像?
标签: c# multithreading mono gtk gtk#