我为我的老板创建了一个图像查看控件,该控件合并了平移,通过鼠标滚轮缩放以及绘制一个框以进行缩放。该控件需要支持非常大的图像文件(即每边数千像素)。螺纹图像缩放子仍然沉没UI
所有的工作,但每当代码缩放图像的控制UI变得反应迟钝。我的老板让我使用线程来设置除了UI之外的缩放代码。缩放代码现在肯定在单独的线程中,但缩放代码正在运行时UI仍然陷入了困境!任何人都可以请帮助我吗?
下面是缩放代码。让我知道如果这不足以帮助我,我会发布你需要的任何代码!
更新:这是整个控制代码。 link text
我为我的老板创建了一个图像查看控件,该控件合并了平移,通过鼠标滚轮缩放以及绘制一个框以进行缩放。该控件需要支持非常大的图像文件(即每边数千像素)。螺纹图像缩放子仍然沉没UI
所有的工作,但每当代码缩放图像的控制UI变得反应迟钝。我的老板让我使用线程来设置除了UI之外的缩放代码。缩放代码现在肯定在单独的线程中,但缩放代码正在运行时UI仍然陷入了困境!任何人都可以请帮助我吗?
下面是缩放代码。让我知道如果这不足以帮助我,我会发布你需要的任何代码!
更新:这是整个控制代码。 link text
看起来GDI + API中有一些全局锁。为了测试我创建了一个基于以下功能
static void test_thread() { Bitmap bmp = new Bitmap(4000, 4000); Graphics g = Graphics.FromImage(bmp); Brush b = Brushes.Red ; for (; ;) { g.FillRectangle(b, 0, 0, bmp.Width, bmp.Height); } }
如果无限循环已经奔空两个线程,CPU使用率在90%以上,使他们利用他们我的CPU的两个内核。使用FillRectangle时,使用率略低于50%,表明只有一个线程可以在时间运行。
所以这是可能的,任何GDI +叫你从GUI线程做而定标过程中,将阻塞,直到规模完成。
我怀疑是因为缩放使用的是所有的CPU,这是用户界面陷入困境。两个线程都可能具有相同的优先级。
尝试降低缩放线程的优先级以允许UI进行响应。
Values for Thread Priority:
Above Normal -> Gives thread higher priority
Below Normal ->Gives thread lower priority
Normal -> Gives thread normal priority
Lowest -> Gives thread lowest priority
Highest -> Gives thread highest priority
so you would probably use:
Thread1.Priority=System.Threading.ThreadPriority.BelowNormal
我以某种方式怀疑是这种情况。我认为最可能的调用是问题。 – 2009-04-30 20:09:36
在创建并启动上述子例程的子程序中,我已将优先级设置为BelowNormal。如果我将优先级设置为最低,则没有区别。 – Ski 2009-04-30 20:12:32
Ski请提供有关如何异步调用此方法的详细信息。这样我们就可以提供帮助! – 2009-04-30 20:14:40
试着用这个代替。
Private Sub Worker(object o)
Dim args as ScaleImageArguments
args = CType(o, ScaleImageArguments)
ScaleImage(args)
End Sub
Private Sub RunScaleImageAsync(ByVal img As Image, ByVal scale As Double)
System.Threading.ThreadPool.QueueUserWorkItem(Worker, _
New ScaleImageArguments(img.Clone, scale))
End Sub
另类 - 使用异步模式。
Private Delegate Sub ScaleImageDelegate(ByRef arg As ScaleImageArguments)
Private Sub BeginScaleImage(ByRef img As Image, ByVal scale As Double)
Dim d As ScaleImageDelegate
d = New ScaleImageDelegate(AddressOf ScaleImage)
d.BeginInvoke(New ScaleImageArguments(img.Clone, scale), _
New AsyncCallback(AddressOf EndScaleImage), d)
End Sub
Private Sub EndScaleImage(ar As IAsyncResult)
Dim d As ScaleImageDelegate
d = CType(ar.AsyncState, ScaleImageDelegate)
d.EndInvoke(ar)
End Sub
然后,只需调用BeginScaleImage以异步运行它。
编辑 - 请参见上面的更正。 EndScaleImage的ar参数应该声明为ByRef,也是BeginScaleImage的img参数。没有理由为什么他们应该通过ByVal!
ImageScaled()如何将图像浸回到UI?
你怎么调用这个方法?你的问题不在这个函数中,而是你试图异步运行它的方式。请发布/描述调用上下文。 – 2009-04-30 20:06:29
滑雪,请尝试我的答案中的最新更新代码。此外,您传递ScaleImageArguments和img参数ByVal。这些应该通过ByRef。虽然这不是线程在执行ScaleImage期间阻塞的原因。 – 2009-04-30 20:52:03