1

私はビットマップがスレッドセーフではないことを知っているので、この回避策を使用します

                   Bitmap[] blobCopies = MakeBlobCopies(bmpBlob, 2);

                    BackgroundWorker bw1 = new BackgroundWorker();
                    bw1.DoWork += new DoWorkEventHandler(bw1_DoWork);
                    bw1.RunWorkerAsync(blobCopies[0]);

                    BackgroundWorker bw2 = new BackgroundWorker();
                    bw2.DoWork += new DoWorkEventHandler(bw2_DoWork);
                    bw2.RunWorkerAsync(blobCopies[1]);

                    DisposeBlobCopies(blobCopies);

Backgroundworkイベントハンドルで、ビットマップにいくつかのフィルターを適用しましたが、アクセス違反の例外が発生します


System.AccessViolationException was unhandled
  Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
  Source=System.Drawing
  StackTrace:
       at System.Drawing.SafeNativeMethods.Gdip.GdipBitmapLockBits(HandleRef bitmap, GPRECT& rect, ImageLockMode flags, PixelFormat format, BitmapData lockedBitmapData)
       at System.Drawing.Bitmap.LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format, BitmapData bitmapData)
       at System.Drawing.Bitmap.LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format)

私はビットマップを破棄していません(メモリの詰まりを避ける必要があります)。しかし、それでもこの例外が発生します。ワーカースレッドから何も返す必要はありませ。これはすぐにこれに近づくことさえできますか?何か案は?

    private Bitmap[] MakeBlobCopies(Bitmap originalBitmap, int n)
    {
        Bitmap[] blobCopies = new Bitmap[n];
        for (int i = 0; i < n; i++)
        {
            blobCopies[i] = (Bitmap)originalBitmap.Clone();
        }
        return blobCopies;
    }
4

1 に答える 1

1

No, bitmaps are thread-safe. They are protected by an internal lock, you'll get an exception when you try to read a bitmap when it is being written to by another thread.

Disposing the bitmaps while the threads are using them is however hazardous, that jerks the floor mat. Especially when you use Bitmap.Clone(), it doesn't make a copy of the pixel data. Only the Bitmap(Image) constructor does that. You'll need to find a better place for the Bitmap.Dispose() call. Like in the DoWork or RunWorkerCompleted event handler, after you are sure that the bitmap isn't going to be accessed anymore.

于 2012-07-08T20:38:31.947 に答える