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

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
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();
 

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 328
Благодарностей
5 431
Баллы
113

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
14
Баллы
18

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 328
Благодарностей
5 431
Баллы
113

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
14
Баллы
18

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
14
Баллы
18
Но с паузами долго :(
 

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 328
Благодарностей
5 431
Баллы
113

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
14
Баллы
18
Я сделал паузу после выполнения кода изложенного выше, меньше секунды если делать паузу, вылетает ошибка к доступу к файлу
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 692
Баллы
113

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
14
Баллы
18

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 692
Баллы
113
ну это же ваш код. вам виднее что надо сделать. как я думаю, LockBits локирует original, а так же ниже по коду та же конструкция с resultBitmap
ну а раз они локируются то другие потоки не смогут с ними ничего сделать. с одной стороны правильно. у вас там операция идет по обработке , а другой поток, хряс и удалил файл. ну или чего там у вас должно произойти при конфликте. так что либо у вас возникает ошибка доступа в другом потоке, либо если тут уберете лок, готовьтесь ловить ошибки именно в этом коде. Выбор всегда за нами :-)
 

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
14
Баллы
18
ну это же ваш код. вам виднее что надо сделать. как я думаю, LockBits локирует original, а так же ниже по коду та же конструкция с resultBitmap
ну а раз они локируются то другие потоки не смогут с ними ничего сделать. с одной стороны правильно. у вас там операция идет по обработке , а другой поток, хряс и удалил файл. ну или чего там у вас должно произойти при конфликте. так что либо у вас возникает ошибка доступа в другом потоке, либо если тут уберете лок, готовьтесь ловить ошибки именно в этом коде. Выбор всегда за нами :-)
Я просто не могу понять почему после выполнения этого кода не успевают разблокироваться файлы пред началом выполнения следующего снипета?
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 692
Баллы
113
Я просто не могу понять почему после выполнения этого кода не успевают разблокироваться файлы пред началом выполнения следующего снипета?
а какой файл то недоступен ? исходник или результирующий ?
 

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
14
Баллы
18

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 692
Баллы
113
Результирующий
ну у вас там прям в самом конце идет сохранение файла. но это только команда, и мне кажется что она не ждет окончания копирования. все на систему сваливает. и если прям сразу обратиться к этому файлу то система еше не закончила с ним, так как скорость выполнения кода и запись файла в разных весовых категориях.
как вариант обернуть код который пытается получить доступ к файлу в следующем снипете в try{} cath{} и зациклить 10 попыток , с паузой в 100-400мс. и тогда как только файл станет доступен, он будет взят в работу.
 

zarufakis

Client
Регистрация
22.03.2019
Сообщения
1 528
Благодарностей
884
Баллы
113

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
14
Баллы
18

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 692
Баллы
113

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
14
Баллы
18

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
14
Баллы
18
Вот
 

Вложения

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 692
Баллы
113
У меня там кубик который чистит 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

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
14
Баллы
18
ну раз кубик , то при ошибке выходит по красной.
вот эту красную линию и заведи на 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
Так?
 

Вложения

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 692
Баллы
113

cherus09

Client
Регистрация
10.10.2016
Сообщения
171
Благодарностей
14
Баллы
18

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