SEHException в многопоточном приложении на MVC 4 с использованием OpenCV

219
24 марта 2018, 13:50

Я пытаюсь найти на большом изображении несколько мелких, используя OpenCV SIFT в VS2017 на C#. Итак, у меня есть отдельные изображения и несколько копий основного, которые хранятся в списке закрытом классом. Теперь, когда я вызываю следующий код, он работает нормально (конечно, это последовательные вызовы):

foreach (var obj in temp)
        {
            results.Add(
                        searchEngine.Run(
                                new AirPhoto(obj.map, path),
                                new AirPhoto(obj.single, obj.adr)))));
        }

Я попытался сделать это быстрее, вызвав все results.Add в многопоточном (многозадачном) режиме:

foreach (var obj in temp)
        {
            tasks.Add(
                Task.Factory.StartNew(() =>
                    results.Add(
                        searchEngine.Run(
                                new AirPhoto(obj.map, path),
                                new AirPhoto(obj.single, obj.adr)))));
        }
        Task.WaitAll(tasks.ToArray());

Когда изображений меньше 10 (например, 2-9), все работает хорошо, но когда их 10 или более, получаю «System.Runtime.InteropServices.SEHException» в OpenCvSharp.CPlusPlus.dll. Я решил разделить изображения на несколько групп на 5 и вызывать их по очереди (первые 5 обработались, затем идёт вторая группа и так далее...):

List<Task> tasks = new List<Task>();
    int i = 0;
    while (i < temp.Count)
    {
        int size = temp.Count;
        tasks.Clear();
        List<Temp> temp1 = new List<Temp>();
        if ((i + 5) < size && i == 0)
        {
            temp1 = temp.Take(5).ToList();
        }
        else if ((i + 5) < size && i != 0)
        {
            temp1 = temp.Skip(i).Take(5).ToList();
        }
        else
        {
            temp1 = temp.Skip(i).ToList();
        }
        foreach (var obj in temp1)
        {
            tasks.Add(
                Task.Factory.StartNew(() =>
                    results.Add(
                        searchEngine.Run(
                                new AirPhoto(obj.map, path),
                                new AirPhoto(obj.single, obj.adr)))));
        }
        Task.WaitAll(tasks.ToArray());
        i += 5;
    }

Но проблема не решается. Иногда (!!!) первые 5 изображений обрабатываются нормально, а ошибка появляется во второй группе, но в большинстве случаев она отображается почти сразу. Блок кода, который вызывает ошибку (в методе searchEngine.Run()):

public Result Run(AirPhoto mainMap, AirPhoto image)
{
    SIFT sift = new SIFT();
    BFMatcher matcher = new BFMatcher();
    Result res = new Result(mainMap, image);
    Mat map = new Mat(res.mainMap.fileName);
    Mat singleImage = new Mat(res.singleImage.fileName);
    Debug.Write(...);
    sift.Run(map, null, out res.mainMap.keypoints, res.mainMap.descriptors);
    sift.Run(singleImage, null, out res.singleImage.keypoints, res.singleImage.descriptors); //error there...
    res.matches = matcher.Match(res.mainMap.descriptors, res.singleImage.descriptors); // or there
    ...
    return res;
}

Я знаю о существовании async/await, но не придумал, как использовать ихв моем случае.

UPD: это приложение ASP NET MVC 4, но в версии WinForms (щас портирую в веб) все работало нормально. Debug/Release/32/64 - не имеет значения.

UPD2: Ни один из вариантов предложенных @Alias в разных режимах не спас(( Фигня в том, что sift.Run(), насколько я понял, является обёрткой над кодом чистых плюсов, а их код я открыть не могу - рефлектор шлёт по матери ибо когда эта либа писалась один создатель знает.

StackTrace:

в OpenCvSharp.CPlusPlus.NativeMethods.nonfree_SIFT_run2_OutputArray(IntPtr obj, IntPtr img, IntPtr mask, IntPtr keypoints, IntPtr descriptors, Int32 useProvidedKeypoints)
в OpenCvSharp.CPlusPlus.SIFT.Run(InputArray img, InputArray mask, KeyPoint[]& keypoints, OutputArray descriptors, Boolean useProvidedKeypoints)
в SharedLogic.SearchEngine.Run(AirPhoto mainMap, AirPhoto image) в D:\CVSharp\SharedLogic\SearchEngine.cs:строка 35

А создаёт исключение изначально

TargetSite {Void nonfree_SIFT_run2_OutputArray(IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, Int32)} System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}

Вопрос не в том, почему оно бросает исключение, а в том, почему именно на сервере? Может, нужно дать IIS больше ресурсов или потоков? Если это возможно, конечно

READ ALSO
Ребят что делать дефендер считает мою программу вирусом?

Ребят что делать дефендер считает мою программу вирусом?

Написал приложение клиент для соц сети на C# и дефендер считает его вирусом что за беспредел? Trojan:Win32/SpriskyW!cl

230
Ошибка при деплое функции на MS SQL Server

Ошибка при деплое функции на MS SQL Server

Пишу пользовательскую функцию для MS SQL Server 2012Внутри использую передачу данных по HTTP и сборку System

209
Переменная _version в библиотченом классе ArrayList

Переменная _version в библиотченом классе ArrayList

Изучаю библиотечный класс ArrayList и не могу понять какую функцию несет переменная private int _version; ? Строка 48:

196
Переход со страницы на страницу в WPF

Переход со страницы на страницу в WPF

Этот вопрос является логическим продолжеием этого вопросаЯ попытался реализовать схему, изложенную здесь , но программа не работает

216