Object is currently in use elsewhere

强颜欢笑 提交于 2019-12-04 07:24:51

the locker object is not static; thus every new instance creates its own locker; you need to create locker as static in order to prevent access from other threads if using multiple objects.

private static Object locker = new Object();

For single object scenario, using a non static class level variable as a locker is proper. If you are employing this scenario I feel that the implementation of Singleton has some problems.

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
        }
    }

}

It doesn't matter whether the object that is locked is static or not. The problem is that the lock(locker) inside the getter method unlocks as soon as the bitmap is returned. The returned reference to the bitmap is not protected by the lock and can be modified at the same time as a call to Refresh occurs.

One possible solution would be to lock on the bitmap itself but that can introduce deadlocks if not done carefully.

In my app the best solution was:

  • copy dir with files to another, tmp. catalog (with guid name)
  • use tmp files per user
  • delete tmp catalog with files in it

In my app there is:

  • each request is 1 min long
  • max users is 120 (intranet application)
  • nobody want to wait 5-10 min for raport to generate

Copy few files add about 0,01-0,2 sek. for each request, is better that static lock on all app and user don't neet to wait 10 min for raport to generate (10 users click generate button in same moment).

        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();
    }

you can clone that image before send it to method

                Image newimg = (Image)img.Clone();
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!