c#的NLua多线程并行执行

多线程的封装 LuaThreadPool.cs

这里是Lua的多线程执行帮助类LuaThreadPool.cs

/// <summary>
/// Lua线程池的信息
/// </summary>
public class LuaThreadPool
{

    /// <summary>
    /// Windows窗体信息
    /// </summary>
    public FrmMain _window { get; set; } = null;
    /// <summary>
    /// 模拟器信息
    /// </summary>
    public SimulatorInfo _simulator { get; set; } = null;
    /// <summary>
    /// Lua的所有线程信息
    /// </summary>
    public Dictionary<int , TaskList> _threads { get; set; } = new Dictionary<int, TaskList>();

}

/// <summary>
/// 任务列表
/// </summary>
public class TaskList
{

    /// <summary>
    /// 取消令牌
    /// </summary>
    public CancellationTokenSource _cancel = null;
    /// <summary>
    /// 令牌的Token信息
    /// </summary>
    public CancellationToken _token;
    /// <summary>
    /// 信号量
    /// </summary>
    public ManualResetEvent _event;
    /// <summary>
    /// 线程信息
    /// </summary>
    public Thread _thread;
    /// <summary>
    /// 线程的运行状态信息
    /// </summary>
    public string _thread_status = "ready";

    /// <summary>
    /// 新建一个线程信息
    /// </summary>
    /// <returns></returns>
    public async Task Start(LuaThreadPool _pool, int _vm_index = 10000)
    {
        //设置信号量
        _event = new ManualResetEvent(true);
        //获取令牌实例化
        _cancel = new CancellationTokenSource();
        _token = _cancel.Token;

        //声明新的线程信息
        _thread = new Thread(new ThreadStart(async () =>
        {
            //实例化乐玩插件对象
            xq.Ilwsoft _lw = new xq.lwsoft();

            //实例化Lua对象
            Lua _lua = new Lua();
            //扩展
            _lua.LuaExtendstion(_pool._window, _pool._simulator, _pool, _vm_index);
            //更改状态信息
            _lua["_thread_status"] = "running";
            //注册乐玩插件
            _lua["lw"] = _lw;
            //执行
            while (!_token.IsCancellationRequested)
            {
                //监听是否暂停
                _event.WaitOne();
                //延迟500ms
                Thread.Sleep(500);
                //执行主方法
                _lua.DoString("xpcall(main, __G__TRACKBACK__);");
            }
        }));

        //单例启动任务
        _thread.SetApartmentState(ApartmentState.STA);
        _thread.Start();
        _thread_status = "running";
    }

    /// <summary>
    /// 停止线程
    /// </summary>
    public void Stop() { _cancel.Cancel(); _thread_status = "stopped"; }

    /// <summary>
    /// 暂停线程
    /// </summary>
    public void Pause() { _event.Reset(); _thread_status = "paused"; }

    /// <summary>
    /// 线程继续
    /// </summary>
    public void Continue() { _event.Set(); _thread_status = "running"; }

}

并行执行的实现

//遍历模拟器信息 然后逐渐开启线程
foreach (SimulatorInfo _sim in _view)
{
    //如果模拟器选择了的话
    if (_sim.choosed == 1)
    {
        //获取当前对应的线程信息
        var _current_script = _scripts.Where(p => p != null && p._simulator.index == _sim.index).FirstOrDefault();
        //如果线程是空的 那么添加
        if (_current_script == null)
        {
            //实例化线程池
            LuaThreadPool _pools = new LuaThreadPool() { _window = this, _simulator = _sim };
            //新建一个线程信息
            TaskList _thread = new TaskList();
            await _thread.Start(_pools, _sim.index * 10000);
            //添加到线程池中
            _pools._threads.Add(_sim.index * 10000, _thread);
            _scripts.Add(_pools);
        }
    }
}

我在LuaThreadPool中的TaskList

1.里面有当前的线程对应的执行状态【_thread_status】
2.里面在Start中,我实例化了lw插件及lua vm虚拟机,因为只能在单例的线程中进行创建,不然会出现内存写保护。当我们需要停止的时候调用暂停直接销毁线程就好了
3.我的Lua扩展请自行根据情况进行扩展,因为多线程的Lua每个虚拟机的情况不同,所以很容易出现异常,所以需要对每个虚拟机进行相同的初始化,确保原始值的统一性。
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值