Блокируется файл после обработки [РЕШЕНО!]

  • Автор темы Автор темы cherus09
  • Дата начала Дата начала

cherus09

Client
Регистрация
10.10.2016
Сообщения
172
Реакции
14
Баллы
18
Подскажите почему-то иногда после обработки изображения, следующий экшен не может получить доступ к этому изображению. Вылетает ошибка "Процесс не может получить доступ к файлу "C:\Users\img\aboutbg-A8.png", так как этот файл используется другим процессом."

Подозрение на то что иногда обрабатываемый файл не успевает освободиться от предыдущего процесса. Что можно сделать?

Вот код обрабатывающий изображения:

C#:
Развернуть Свернуть Копировать
Random rand = new Random();
string expFile = project.Variables["rassherenie_images_file"].Value; //Расширение файла
string nameFile = project.Variables["name_prefix"].Value; // Имя файла


//Ставим  пиксель в рандомное место
Bitmap original = (Bitmap)Image.FromFile(project.Variables["image_file_dlya_obrabotki"].Value);
original.SetPixel(rand.Next(original.Width), rand.Next(original.Height), Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256), rand.Next(256)));
//Ставим  пиксель в рандомное место

//Обрезаем картинку
int min = 1; //Минимум на сколько обрезать картинку
int max = 1; //Максимум на сколько обрезать картинку
if (expFile != "png"){
Rectangle cropArea = new Rectangle(rand.Next(min,max), rand.Next(min,max), (original.Width - rand.Next(min * 1,max * 1)), (original.Height - rand.Next(min * 1,max * 1)));
original = original.Clone(cropArea, original.PixelFormat);
}
//Обрезаем картинку

//Меняем контраст
//Случайный уровень контрастности 0т 16 до 28. Чем он выше, тем контрастнее и ярче картинка на выходе
Random rnd = new Random();
int threshold = rnd.Next(1,3);
//Bitmap original = (Bitmap)Image.FromFile(project.Directory + "/contr1.jpg");
System.Drawing.Imaging.BitmapData sourceData = original.LockBits(new Rectangle(0, 0,
                                original.Width, original.Height),
                                System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

byte[] pixelBuffer = new byte  [sourceData.Stride * sourceData.Height];
System.Runtime.InteropServices.Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length);
original.UnlockBits(sourceData);

double contrastLevel = Math.Pow((100.0 + threshold) / 100.0, 2);
double blue = 0;
double green = 0;
double red = 0;
for (int k = 0; k + 4 < pixelBuffer.Length; k += 4) {
    blue = ((((pixelBuffer[k] / 255.0) - 0.5) * contrastLevel) + 0.5) * 255.0;
    green = ((((pixelBuffer[k + 1] / 255.0) - 0.5) * contrastLevel) + 0.5) * 255.0;
    red = ((((pixelBuffer[k + 2] / 255.0) - 0.5) * 
                    contrastLevel) + 0.5) * 255.0;   
        if  (blue > 255)
        { blue = 255; }
        else if  (blue < 0)
        { blue = 0; }

        if (green > 255)
        { green = 255; }
        else if (green < 0)
        { green = 0; }
  
        if (red > 255)
        { red = 255; }
        else if (red < 0)
        { red = 0; }

        pixelBuffer[k] = (byte)blue;
        pixelBuffer[k + 1] = (byte)green;
        pixelBuffer[k + 2] = (byte)red;
    }
Bitmap resultBitmap = new Bitmap(original.Width, original.Height);
System.Drawing.Imaging.BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0,
                                resultBitmap.Width, resultBitmap.Height),
                                System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
System.Runtime.InteropServices.Marshal.Copy(pixelBuffer, 0, resultData.Scan0, pixelBuffer.Length);
resultBitmap.UnlockBits(resultData);
//Меняем контраст

//Сохраняем картинку
resultBitmap.Save( project.Directory + @"\temp\" + nameFile + "." + expFile);
resultBitmap.Dispose();
 
Но с паузами долго :(
 
Я сделал паузу после выполнения кода изложенного выше, меньше секунды если делать паузу, вылетает ошибка к доступу к файлу
 
ну это же ваш код. вам виднее что надо сделать. как я думаю, LockBits локирует original, а так же ниже по коду та же конструкция с resultBitmap
ну а раз они локируются то другие потоки не смогут с ними ничего сделать. с одной стороны правильно. у вас там операция идет по обработке , а другой поток, хряс и удалил файл. ну или чего там у вас должно произойти при конфликте. так что либо у вас возникает ошибка доступа в другом потоке, либо если тут уберете лок, готовьтесь ловить ошибки именно в этом коде. Выбор всегда за нами :)
 
ну это же ваш код. вам виднее что надо сделать. как я думаю, LockBits локирует original, а так же ниже по коду та же конструкция с resultBitmap
ну а раз они локируются то другие потоки не смогут с ними ничего сделать. с одной стороны правильно. у вас там операция идет по обработке , а другой поток, хряс и удалил файл. ну или чего там у вас должно произойти при конфликте. так что либо у вас возникает ошибка доступа в другом потоке, либо если тут уберете лок, готовьтесь ловить ошибки именно в этом коде. Выбор всегда за нами :-)
Я просто не могу понять почему после выполнения этого кода не успевают разблокироваться файлы пред началом выполнения следующего снипета?
 
Я просто не могу понять почему после выполнения этого кода не успевают разблокироваться файлы пред началом выполнения следующего снипета?
а какой файл то недоступен ? исходник или результирующий ?
 
Результирующий
ну у вас там прям в самом конце идет сохранение файла. но это только команда, и мне кажется что она не ждет окончания копирования. все на систему сваливает. и если прям сразу обратиться к этому файлу то система еше не закончила с ним, так как скорость выполнения кода и запись файла в разных весовых категориях.
как вариант обернуть код который пытается получить доступ к файлу в следующем снипете в try{} cath{} и зациклить 10 попыток , с паузой в 100-400мс. и тогда как только файл станет доступен, он будет взят в работу.
 
следующий экшен не может получить доступ к этому изображению.
Сделать цикл с проверкой. При положительном результате идем дальше,при ошибке, снва в цикл.
 
Вот
 

Вложения

  • 2020-06-19_21-02-33.png
    2020-06-19_21-02-33.png
    11 KB · Просмотры: 9
У меня там кубик который чистит Exif
ну раз кубик , то при ошибке выходит по красной.
вот эту красную линию и заведи на C# код, а там напиши
C#:
Развернуть Свернуть Копировать
Thread.Sleep(50);
int Try = int.Parse(project.Variables["try_1"].Value) -1 ;
project.Variables["try_1"].Value = Try.ToString();
if ( Try <=0 ) throw new Exception();
else return 0;

переменную заведи try_1 и кубик инициализации перед обработкой сделай.
примерно вот так.
58525
 
  • Оценить
Реакции: cherus09 и finista
ну раз кубик , то при ошибке выходит по красной.
вот эту красную линию и заведи на C# код, а там напиши
C#:
Развернуть Свернуть Копировать
Thread.Sleep(50);
int Try = int.Parse(project.Variables["try_1"].Value) -1 ;
project.Variables["try_1"].Value = Try.ToString();
if ( Try <=0 ) throw new Exception();
else return 0;

переменную заведи try_1 и кубик инициализации перед обработкой сделай.
примерно вот так.
Посмотреть вложение 58525
Так?
 

Вложения

  • 2020-06-19_21-41-30.png
    2020-06-19_21-41-30.png
    15,4 KB · Просмотры: 16

Кто просматривает тему: (Всего: 0, Пользователи: 0, Гости: 0)