5

このエラーが発生しました。これは、同じ Bitmap オブジェクトが異なるスレッドによってアクセスされていることが原因のようです。しかし、私はどこでもロックを使用しています。

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

クラスMySingleInstanceClassには 1 つのインスタンスしかありません。への呼び出しとMyImageRefresh()異なるスレッドからの呼び出し。私が理解している限り、内部のコードlock(locker)は別のスレッドで終了するまで実行されませんが、それでもエラーが発生します。誰でもコードの欠陥を指摘できますか?

例外は次のようになります。

System.Drawing.dll で、タイプ 'System.InvalidOperationException' の初回例外が発生しました

エラー: オブジェクトは現在別の場所で使用されています。

System.Drawing.Graphics.FromImage(イメージ イメージ) で

at (var g = Graphics.FromImage(myImage); を含む行を指します)

4

4 に答える 4

1

私のアプリでは、最善の解決策は次のとおりです。

  • dir をファイルとともに別の tmp にコピーします。カタログ (GUID 名付き)
  • ユーザーごとに tmp ファイルを使用する
  • ファイルを含む tmp カタログを削除する

私のアプリには次のものがあります:

  • 各リクエストの長さは 1 分です
  • 最大ユーザー数は 120 (イントラネット アプリケーション)
  • 報告書が生成されるまで 5 ~ 10 分待ちたい人はいません

いくつかのファイルをコピーすると、約 0.01 ~ 0.2 秒かかります。リクエストごとに、すべてのアプリを静的にロックし、ユーザーがラポートが生成されるまで 10 分間待つ必要がないことをお勧めします (10 人のユーザーが [生成] ボタンを同時にクリックします)。

        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();
    }
于 2014-12-18T11:01:00.347 に答える