2010-06-14 67 views
3

我只是想知道,是Graphics.DrawImage()异步? 我正在努力解决线程安全问题,无法找出问题所在。Graphics.DrawImage是异步的吗?

如果我使用的GUI线程以下代码:

protected override void OnPaint(PaintEventArgs e) 
{ 
    lock (_bitmapSyncRoot) 
    { 
     e.Graphics.DrawImage(_bitmap, _xPos, _yPos); 
    } 
} 

而且有下面的代码在一个单独的线程:

private void RedrawBitmapThread() 
{ 
    Bitmap newBitmap = new Bitmap(_width, _height); 
    // Draw bitmap // 

    Bitmap oldBitmap = null; 
    lock (_bitmapSyncRoot) 
    { 
     oldBitmap = _bitmap; 
     _bitmap = newBitmap; 
    } 
    if (oldBitmap != null) 
    { 
     oldBitmap.Dispose(); 
    } 
    Invoke(Invalidate); 
} 

莫非是解释一个accessviolation例外?

该代码运行在Windows Mobile 6.1设备上,结构紧凑3.5。

编辑:

没关系,它也发生在该方法在同一个线程得到执行..

+0

这篇文章可能会揭示一些:http://stackoverflow.com/questions/2798812/net-controls-why-arent-all-calls-thread-safe/2798859#2798859 – 2010-06-14 08:21:42

回答

0

嗯,是的DrawImage不异步。该框架不会自动使其异步。此外,大多数.NET中的所有异步操作都以'Begin'开头,只是fyi。

我不知道在哪里你的错误是从哪里来的,但你能:

  • 告诉我们哪一行的AccessViolationException是扔?
  • 确保_bitmapSyncRoot被初始化?
+0

我知道'开始'方法,但我很确定不是所有的异步方法都返回一个IAsyncResult? 要回答以下问题: - 这是一个非管理性例外,我的应用程序当场死亡,博士。 watson显示一个异常对话框。 - 是的,我初始化了SyncRoot对象 – Roy 2010-06-14 09:06:57

+0

感谢您的信息。你能解释在用户界面上如何使用各种_<...>位图吗?也许这是你的电话给oldBitmap.Dispose(),这是导致问题? 另外,你确定OnPaint是从GUI线程调用的吗?您可以执行InvokeRequired检查以确保万一出现问题。 – Chad 2010-06-14 18:19:55

+0

位图是listview-like-control中的项目。 (每个项目有1个位图)我在这里简化了代码,但想法是为项目设置一个无效队列,以便单独的线程可以处理重新绘制项目。关于onpaint:我只调用Invalidate,所以OnPaint由OS/CF处理。 – Roy 2010-06-15 11:14:37

1

是的,是同步的。但是你在这段代码中做了更大的假设,假设创建任何Graphics对象都是线程安全的。 Afaik它是GDI +的桌面版本。在像WM这样有限的资源操作系统上这不太可能。没有任何东西可以锁定,用于绘画的东西是在您无法触摸的代码中创建的。

+0

确切地说,我在哪里创建一个图形对象? – Roy 2010-06-14 09:14:16

+0

在代码中评论//绘制位图。 CF在调用OnPaint()之前创建一个。 – 2010-06-14 10:51:05

+0

没错,忘了。绘图都发生在同一个线程内,所以这不应该成为问题。我想下面不应该抛出任何异常:Graphics.FromImage(...),Graphics.Draw ...(...),Graphics.Dispose()。对? – Roy 2010-06-15 11:22:05