Как чисто остановить поток.NET, на котором запущена функция dll matlab

80
11

Я скомпилировал DLL Matlab с тегом namespace flagTest и тестом имени класса с помощью этой функции:

function [ ] = flagTest( flag )
while flag
disp(flag);
pause(1);
end
end

Я могу назвать эту функцию dll в С# следующим образом:

using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//create test class object
flagTest.test T = new flagTest.test();
MWLogicalArray flag = new MWLogicalArray(true);
//call matlab function flagTest
T.flagTest(flag);
}
}
}

Прошу прощения, если это вызывает путаницу, так как я называю как мое пространство имен, так и функцию flagTest.

Теперь я хочу поместить этот T.flagTest(flag) функции T.flagTest(flag) в поток (который я знаю, как это сделать) и изменить значение flag на false когда пользователь нажимает кнопку в пользовательском интерфейсе, чтобы остановить поток, В реальной функции matlab в нашем приложении мне нужно будет выполнить некоторую работу, например, закончить чтение текущего файла и записать данные в память на диск, прежде чем я смогу остановить поток функций. Я не могу просто остановить поток, не делая ничего в функции matlab.

Мне интересно, если так или иначе, чтобы достичь этой функциональности, поскольку я не мог понять, как передать объект по ссылке из.NET в Matlab.

спросил(а) 2021-01-19T16:20:28+03:00 9 месяцев назад
1
Решение
92

Почему вы не инкапсулируете флаг, который управляет вашим циклом в ваш test класс? Например:

classdef test < handle
properties (Access = private)
Running
end

methods
function Start(this)
if (this.Running)
disp('Already Running');
return;
end

this.Running = true;
disp('Started');

while (this.Running)
pause(1);
disp('Running');
end

disp('Stopped');
end

function Stop(this)
this.Running = false;
end
end
enn

Затем в вашей сборке C#:

namespace ConsoleApplication1
{
public static class Program
{
public static void Main(String[] args)
{
flagTest.test T = new flagTest.test();
T.Start();

while (true)
{
String command = Console.ReadLine();

if (command.ToLowerInvariant() == "stop")
{
T.Stop();
break;
}
}
}
}
}

При этом этот подход не имеет никакого отношения к многопоточности. Если вы хотите работать с многопоточным процессом, вам необходимо рассмотреть три важные вещи:

как сохранить прогресс ваших работников, когда потоки убиты как реализовать свойство сигнала отмены как управлять сигналом отмены

Это всего лишь пример, но его необходимо улучшить:

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

List<Thread> threads = new List<Thread>();

for (Int32 i = 0; i < 5; ++i)
{
flagTest.test T = new flagTest.test();
token.Register(() => T.Stop());

Thread thread = new Thread(() => T.Start());
thread.IsBackground = true;

threads.Add(thread);

thread.Start();
}

Затем, когда пользователь запросит отмену, просто позвоните:

cts.Cancel();
cts.Dispose();

ответил(а) 2021-01-19T16:20:28+03:00 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема