如何干净地停止运行matlab dll函数的.NET线程

时间:2017-12-12 21:55:21

标签: c# multithreading matlab dll pass-by-reference

我用这个函数编译了一个带有命名空间flagTest和类名测试的Matlab DLL:

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

我可以在c#中调用这个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)函数调用放在一个线程上(我知道该怎么做),并将flag的值更改为false用户单击UI上的按钮以停止线程。在我们的应用程序中真正的matlab函数中,我需要完成一些工作,例如完成读取当前文件并将内存中的数据写入磁盘,然后才能停止函数线程。我不能在没有在matlab函数中做任何事情的情况下停止线程。

我想知道是否还有实现此功能,因为我无法弄清楚如何通过引用将对象从.NET传递给Matlab。

1 个答案:

答案 0 :(得分:0)

为什么不将控制循环的标志封装到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;
                }
            }
        }
    }
}

这就是说,这种方法与多线程无关。如果你想使用多线程,你必须考虑三个重要的事情:

  1. 如何在线程被杀死时保存工作人员进度
  2. 如何实现取消信号属性
  3. 如何控制取消信号
  4. 这只是一个例子,但必须加以改进:

    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();