The facility is currently being used elsewhere.

I get this error and it looks like this because different threads are accessing the same Bitmap object. However, I use locks all over it.

public class MySingleInstanceClass
{
    private Object locker = new Object();

    private Bitmap myImage = new Bitmap(100, 100);

    public Bitmap MyImage
    {
        get
        {
            lock (locker)
                return myImage;
        }
        private set
        {
            lock (locker)
                myImage = value;
        }
    }

    private void Refresh()
    {
        lock (locker)
        {
            var g = Graphics.FromImage(myImage);
            // do more processing
        }
    }
}

The class MySingleInstanceClasswill have only one instance. Challenges MyImageand Refresh()can come from different threads. As far as I understand, the code inside lock(locker)will not be executed until it finishes in another thread, but I still get the error. Can anyone point out a flaw in the code?

The exception is as follows:

The first case of an exception of type "System.InvalidOperationException" occurred in System.Drawing.dll

Error: The object is currently being used elsewhere.

in System.Drawing.Graphics.FromImage (image image)

at ( , var g = Graphics.FromImage(myImage);)

+5
4

locker ; , ; locker , .

private static Object locker = new Object();

. , , Singleton .

UPDATE:

public sealed class MySingleInstanceClass
{
    private static volatile MySingleInstanceClass instance;
    private static object syncRoot = new Object();
    private Bitmap myImage;

    private MySingleInstanceClass() 
    {
        myImage = new Bitmap(100, 100);
    }

    public static MySingleInstanceClass Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new MySingleInstanceClass();
                }
            }

            return instance;
        }
    }  

    public Bitmap MyImage
    {
        get
        {
            lock (syncRoot)
                return myImage;
        }
        private set
        {
            lock (syncRoot)
                myImage = value;
        }
    }

    public void Refresh()
    {
        lock (syncRoot)
        {
            var g = Graphics.FromImage(myImage);
            // do more processing
        }
    }

}
+9

, , , . , lock(locker) getter , . Refresh.

, , .

+4

:

  • , tmp. ( )
  • tmp
  • tmp

:

  • 1 .
  • Maximum Users - 120 (Intranet Application)
  • nobody wants to wait 5-10 minutes to create a raport

Copy several files, add about 0.01-0.2 seconds. for each request, it is better that static blocking for all applications and users is not performed, to wait 10 minutes for raport to be generated (10 users press the generate button at the same time).

        private void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
    {
        // Get the subdirectories for the specified directory.
        DirectoryInfo dir = new DirectoryInfo(sourceDirName);
        DirectoryInfo[] dirs = dir.GetDirectories();

        if (!dir.Exists)
        {
            throw new DirectoryNotFoundException(
                "Source directory does not exist or could not be found: "
                + sourceDirName);
        }

        // If the destination directory doesn't exist, create it. 
        if (!Directory.Exists(destDirName))
        {
            Directory.CreateDirectory(destDirName);
        }

        // Get the files in the directory and copy them to the new location.
        FileInfo[] files = dir.GetFiles();
        foreach (FileInfo file in files)
        {
            string temppath = Path.Combine(destDirName, file.Name);
            file.CopyTo(temppath, false);
        }

        // If copying subdirectories, copy them and their contents to new location. 
        if (copySubDirs)
        {
            foreach (DirectoryInfo subdir in dirs)
            {
                string temppath = Path.Combine(destDirName, subdir.Name);
                DirectoryCopy(subdir.FullName, temppath, copySubDirs);
            }
        }
    }


        private void DeleteReportExecutionDirectory(string dirPath)
    {
        System.IO.DirectoryInfo downloadedMessageInfo = new DirectoryInfo(dirPath);
        foreach (FileInfo file in downloadedMessageInfo.GetFiles())
        {
            file.Delete();
        }
        foreach (DirectoryInfo dir in downloadedMessageInfo.GetDirectories())
        {
            dir.Delete(true);
        }
        downloadedMessageInfo.Delete();
    }
+1
source

you can clone this image before sending it to the method

                Image newimg = (Image)img.Clone();
0
source

All Articles