• 异步编程设计模式


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Scripting.Hosting;
    using IronPython.Hosting;
    using System.Threading;
    using System.Windows.Forms;
    using System.Reflection;
    using System.ComponentModel;
    
    namespace IronPythonDebugger
    {
        public class IronPythonDebugger : IIronPythonDebugger
        {
            private ScriptEngine _engine;
    
            private ScriptScope _scope;
    
            private string _source;
    
            private string _debugSource;
    
            private ScriptSource _debugScriptSource;
    
            private Dictionary<int, bool> _breakpoints;
    
            private Thread _debugThread;
    
            private int _currentLine = 0;//从1开始计算
    
            private int _logicStartLine;//从1开始计算
    
            private ScriptBackgroundExecute _backgroundExecute;
    
            private bool _debugging = false;
    
            private int _sourceLineCount;
    
            private const string BACKGROUND_BREAK_CODE = "_backgroundExecute.Break()";
    
            private Action<int> _breakCallback;
    
            private int _nextBreakLine;
    
            private bool _debugThreadSleep = false;
    
            private AsyncOperation _asyncOp;
    
            private Action _exec;
    
            private SendOrPostCallback _onBreakCallback;
    
            private void Execute()
            {
                try
                {
                    _debugScriptSource.Execute(_scope);
                }
                catch (DebugStopException)
                {
                }
                catch (ThreadAbortException)
                {
                }
                catch (Exception e)
                {
                    throw new Exception(e.Message);
                }
                finally
                {
                    Stop();
                }
            }
    
            private void BackgroundBreakCallback()
            {
                if (!_debugging)
                {
                    throw new DebugStopException();
                }
                _currentLine++;
                if (_currentLine == _nextBreakLine)
                {
                    _debugThreadSleep = true;
                    //if (_breakCallback != null)
                    //{
                    //    _breakCallback(_currentLine);
                    //}
                    _asyncOp.Post(_onBreakCallback, _currentLine);
                    WaitDebugThreadContinue();
                }
            }
    
            private void OnBreakCallback(object lineNumber)
            {
                if (Break != null)
                {
                    Break(this, new BreakEventArgs((int)lineNumber));
                }
                else if (_breakCallback != null)
                {
                    _breakCallback((int)lineNumber);
                }
            }
    
            private void WaitDebugThreadContinue()
            {
                while (_debugThreadSleep)
                {
                    Thread.Sleep(100);
                }
            }
    
            private void AddBackgroundBreakCode()
            {
                string[] lines = _source.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
                _sourceLineCount = lines.Length;
                _logicStartLine = GetLogicStartLine(lines);//获取第一行逻辑代码的行号
                _debugSource = string.Empty;
                for (int i = 0; i < _sourceLineCount; i++)
                {
                    if (!string.IsNullOrEmpty(_debugSource))
                    {
                        _debugSource += Environment.NewLine;
                    }
                    if (i >= _logicStartLine - 1)
                    {
                        _debugSource += BACKGROUND_BREAK_CODE + Environment.NewLine;
                    }
                    _debugSource += lines[i];
                }
            }
    
            ////import clr,sys
            ////clr.AddReference('TestClass')
            ////clr.AddReference('System.Windows.Forms')
            ////from TestClass import *
            ////from System.Windows.Forms import *
    
            ////c1 = Class1()
            ////c1.Name = "c1"
            ////MessageBox.Show(c1.Name)
            ////child = Class1()
            ////child.Name = "child1"
            ////c1.Child = child
            ////MessageBox.Show(c1.Child.Name)
            private int GetLogicStartLine(string[] lines)
            {
                int startLine = 1;
                for (int i = 0; i < lines.Length;i++ )
                {
                    string line = lines[i].ToLower();
                    if (line.IndexOf("import") < 0
                        && line.IndexOf("clr") < 0
                        && line.IndexOf("from") < 0)
                    {
                        startLine = i + 1;
                        break;
                    }
                }
                return startLine;
            }
    
            private int GetNextBreakLine(int currentLine)
            {
                int next = -1;
                _breakpoints.OrderBy(breakpoint => breakpoint.Key);
                foreach (KeyValuePair<int, bool> breakpoint in _breakpoints)
                {
                    if (breakpoint.Value && breakpoint.Key > currentLine)
                    {
                        next = breakpoint.Key;
                        break;
                    }
                }
                return next;
            }
    
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
            public event Action<object, BreakEventArgs> Break;
    
            public ScriptEngine Engine
            {
                get
                {
                    return _engine;
                }
            }
    
            public ScriptScope Scope
            {
                get
                {
                    return _scope;
                }
            }
    
            public string Source
            {
                get
                {
                    return _source;
                }
            }
    
            public Action<int> BreakCallback
            {
                get
                {
                    return _breakCallback;
                }
    
                set
                {
                    _breakCallback = value;
                }
            }
    
            public IronPythonDebugger()
            {
                _engine = Python.CreateEngine();
                _scope = _engine.CreateScope();
                _scope.SetVariable("_backgroundExecute", _backgroundExecute);
                _breakpoints = new Dictionary<int, bool>();
                _backgroundExecute = new ScriptBackgroundExecute(BackgroundBreakCallback);
                _exec = new Action(Execute);
                _onBreakCallback = new SendOrPostCallback(OnBreakCallback);
            }
    
            public void InitialDebugger()
            {
                if (_debugging)
                {
                    throw new Exception("调试器正在调试中!");
                }
                _scope = _engine.CreateScope();
                _scope.SetVariable("_backgroundExecute", _backgroundExecute);
                _breakpoints.Clear();
            }
    
            public void InitialDebugger(List<int> breakpoints)
            {
                InitialDebugger();
                foreach (int breakpoint in breakpoints)
                {
                    _breakpoints[breakpoint] = true;
                }
            }
    
            public void ClearBreakpoints()
            {
                _breakpoints.Clear();
            }
    
            public void Start(string source)
            {
                if (_debugging)
                {
                    throw new Exception("调试器正在调试中!");
                }
                _source = source;
                AddBackgroundBreakCode();
                _debugScriptSource = _engine.CreateScriptSourceFromString(_debugSource);
                _currentLine = _logicStartLine - 1;
                _debugThreadSleep = false;
                _nextBreakLine = GetNextBreakLine(0);
                //_debugThread = new Thread(Execute);
                //_debugThread.Start();
                _asyncOp = AsyncOperationManager.CreateOperation(1);
                _exec.BeginInvoke(null, null);
                _debugging = true;
            }
    
            public void Stop()
            {
                if (_debugging)
                {
                    _debugging = false;
                    _debugThreadSleep = false;
                    //if (_debugThread != null && _debugThread.IsAlive)
                    //{
                    //    _debugThread.Abort();
                    //}
                }
            }
    
            public void AddBreakpoint(int line)
            {
                _breakpoints[line] = true;
            }
    
            public void AddBreakpoints(List<int> lines)
            {
                foreach (int line in lines)
                {
                    AddBreakpoint(line);
                }
            }
    
            public void DeleteBreakpoint(int line)
            {
                _breakpoints[line] = false;
            }
    
            public void DeleteBreakpoints(List<int> lines)
            {
                foreach (int line in lines)
                {
                    DeleteBreakpoint(line);
                }
            }
    
            public void StepOver()
            {
                if (!_debugging)
                {
                    throw new Exception("调试器未开始调试!");
                }
                _nextBreakLine++;
                _debugThreadSleep = false;
            }
    
            public void StepInto()
            {
                MessageBox.Show("暂不支持逐语句调试!");
            }
    
            public void StepOut()
            {
                MessageBox.Show("暂不支持跳出调试!");
            }
    
            public void Continue()
            {
                if (!_debugging)
                {
                    throw new Exception("调试器未开始调试!");
                }
                _nextBreakLine = GetNextBreakLine(_currentLine);
                _debugThreadSleep = false;
            }
    
            public string GetValueAsString(string variable)
            {
                string value = string.Empty;
                try
                {
                    string[] names = variable.Split('.');
                    object obj = _scope.GetVariable(names[0]);
                    for (int i = 1; i < names.Length; i++)
                    {
                        Type type = obj.GetType();
                        PropertyInfo pi = type.GetProperty(names[i]);
                        obj = pi.GetValue(obj, null);
                    }
                    value = obj.ToString();
                }
                catch (Exception e)
                {
                    throw new Exception(e.Message);
                }
                return value;
            }
    
            public bool IsDebugging()
            {
                return _debugging;
            }
        }
    
        public class BreakEventArgs : EventArgs
        {
            public int LineNumber;
    
            public BreakEventArgs(int lineNumber)
            {
                this.LineNumber = lineNumber;
            }
        }
    
        public class DebugStopException : Exception
        {
        }
    }
  • 相关阅读:
    搭建SpringCloud之注册中心Eureka
    学习角色管理模块错误总结---基于SpringMVC框架
    【转】Eclipse 单步调试
    [转]MyBatis的foreach语句详解
    解决pom.xml文件 ---- web.xml is missing and <failOnMissingWebXml> is set to true
    解决Dynamic Web Module 3.0 Requires Java 1.6 or newer
    用maven在eclipse用spring建javaweb工程(一)
    【转载】Eclipse 断点调试
    学习大神笔记之“MyBatis学习总结(三)”
    学习大神笔记之“MyBatis学习总结(二)”
  • 原文地址:https://www.cnblogs.com/chengshuiqiang/p/4479071.html
Copyright © 2020-2023  润新知