繁体   English   中英

C#中的位图上的线程安全

[英]Threadsafe over Bitmap in C#

谁能告诉我为什么这个代码是错误的,以及我如何必须对其进行修改才能创建一个简单的,保证了线程安全访问的位图?

public static class ThreadSafe
{
    public static readonly object _locker = new object();
    public static Bitmap _snapshot;

    public static Bitmap Snapshot
    {
        get
        {
            lock (_locker)
            {
                return _snapshot;
            }
        }
        set
        {
            lock (_locker)
            {
                _snapshot = value;
            }
        }
    }

}

编辑我要如何使用该位图:

  • 线程A以这种方式使用位图:

新的位图(ThreadSafe.Snapshot,新的System.Drawing.Size(320,240));

  • 线程B以这种方式使用位图:

ThreadSafe.Snapshot =新的位图(target,新的System.Drawing.Size(320,240));

如果这些是位图仅做的两件事:

new Bitmap(ThreadSafe.Snapshot, new System.Drawing.Size(320, 240));
ThreadSafe.Snapshot = new Bitmap(target, new System.Drawing.Size(320, 240));

然后恭喜,您已经是线程安全的,根本不需要任何额外的工作(只需添加volatile ):

public static class ThreadSafe
{
    public static volatile Bitmap Snapshot;
}

我的解决方案,使用快照副本的dispose实现:

public static class ThreadSafe
{
    private static readonly object _locker = new object();
    private static Bitmap _snapshot;

    public static Bitmap GetSnapshot(int width, int height)
    {
        lock (_locker)
        {
            if (_snapshot == null)
                return null;

            return new Bitmap(_snapshot, new Size(width, height));
        }
    }

    public static void SetSnapshot(Bitmap source, int width, int height)
    {
        var copy = new Bitmap(source, new Size(width, height));
        lock (_locker)
        {
            if (_snapshot != null)
                _snapshot.Dispose();
            _snapshot = copy;
        }
    }
}

遵循位图文档中的线程安全准则;

此类型的任何公共static(在Visual Basic中为Shared)成员都是线程安全的。 不保证任何实例成员都是线程安全的。

...这应该接近最小锁定实现;

public static class ThreadSafe
{
    private static readonly object BitmapLock = new object();
    private static Bitmap _snapshot;

    public static Bitmap Snapshot
    {
        get
        {
            lock (BitmapLock)
                return new Bitmap(_snapshot);
        }
        set
        {
            Bitmap oldSnapshot;
            Bitmap newSnapshot = new Bitmap(value, new Size(320, 240));
            lock (BitmapLock) 
            {
                oldSnapshot = _snapshot;
                _snapshot = newSnapshot;
            }
            if (oldSnapshot != null)
                oldSnapshot.Dispose();
        }
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM