异步编程设计模式 - IronPythonDebugger
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 = ;//从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();
}
} 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 = ; i < _sourceLineCount; i++)
{
if (!string.IsNullOrEmpty(_debugSource))
{
_debugSource += Environment.NewLine;
}
if (i >= _logicStartLine - )
{
_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 = ;
for (int i = ; i < lines.Length;i++ )
{
string line = lines[i].ToLower();
if (line.IndexOf("import") <
&& line.IndexOf("clr") <
&& line.IndexOf("from") < )
{
startLine = i + ;
break;
}
}
return startLine;
} private int GetNextBreakLine(int currentLine)
{
int next = -;
_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 - ;
_debugThreadSleep = false;
_nextBreakLine = GetNextBreakLine();
//_debugThread = new Thread(Execute);
//_debugThread.Start();
_asyncOp = AsyncOperationManager.CreateOperation();
_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[]);
for (int i = ; 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
{
}
}
异步编程设计模式 - IronPythonDebugger的更多相关文章
- 异步编程设计模式Demo - AsyncComponentSample
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.C ...
- 异步编程设计模式Demo - PrimeNumberCalculator
using System; using System.Collections; using System.Collections.Specialized; using System.Component ...
- [.net 多线程]异步编程模式
.NET中的异步编程 - EAP/APM 从.NET 4.5开始,支持的三种异步编程模式: 基于事件的异步编程设计模式 (EAP,Event-based Asynchronous Pattern) 异 ...
- JavaScript异步编程的主要解决方案—对不起,我和你不在同一个频率上
众所周知(这也忒夸张了吧?),Javascript通过事件驱动机制,在单线程模型下,以异步的形式来实现非阻塞的IO操作.这种模式使得JavaScript在处理事务时非常高效,但这带来了很多问题,比如异 ...
- C#基础系列——异步编程初探:async和await
前言:前面有篇从应用层面上面介绍了下多线程的几种用法,有博友就说到了async, await等新语法.确实,没有异步的多线程是单调的.乏味的,async和await是出现在C#5.0之后,它的出现给了 ...
- C#编程总结(六)异步编程
C#编程总结(六)异步编程 1.什么是异步? 异步操作通常用于执行完成时间可能较长的任务,如打开大文件.连接远程计算机或查询数据库.异步操作在主应用程序线程以外的线程中执行.应用程序调用方法异步执行某 ...
- node.js整理 06异步编程
回调 异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了 function heavyCompute(n, callback) { var count = 0, i, j; for (i = ...
- 你所必须掌握的三种异步编程方法callbacks,listeners,promise
目录: 前言 Callbacks Listeners Promise 前言 coder都知道,javascript语言运行环境是单线程的,这意味着任何两行代码都不能同时运行.多任务同时进行时,实质上形 ...
- NodeJS学习之异步编程
NodeJS -- 异步编程 NodeJS最大的卖点--事件机制和异步IO,对开发者并不透明 代码设计模式 异步编程有很多特有的代码设计模式,为了实现同样的功能,使用同步方式和异步方式编写代码会有很大 ...
随机推荐
- 树莓派设置固定ip
2016发布的rasbian采用的网络机制是dhcpcd: 不能使用以前的修改配置文件/etc/network/interfaces: 新的配置方式保持/etc/network/interfaces不 ...
- 51单片机引脚ALE/PROG/PSEN/EA/Vpp
51单片机的4个控制引脚,其中一个引脚是复位引脚(RST/Vpd),RST是复位引脚,当RST输入端保持2个机器周期以上高电平时,就实现复位. ALE/PROG是地址锁存允许信号输出端,在读写外部存储 ...
- 开始使用Logstash
开始使用Logstash 本节将指导处理安装Logstash 和确认一切是运行正常的, 后来的章节处理增加负载的配置来处理选择的使用案例. 这个章节包含下面的主题: Installing Logsta ...
- VC++如何在程序中用代码注册和卸载ocx控件(代码)
方法一:在dos或Windows命令行下运行:regsvr32 ocxname.ocx 注册 示例:regsvr32 netshare.ocx //注册netshare.ocx控件regsvr ...
- poj1006 ( hdu1370 ):中国剩余定理裸题
裸题,没什么好说的 第一个中国剩余定理 写暴力都过了..可见这题有多水 代码: #include<iostream> #include<stdio.h> #include< ...
- C# - 创建List属性的简单方法
不用担心List没有创建问题. private ObservableCollection<EquipmentItem> _optionalCollection; public Observ ...
- html checkbox全选或者全不选
/* 全选或全不选 */ function CheckedAllOrNo() { var arr = $(':checkbox'); for (var i = 1; i < arr.length ...
- spring Scurity终于测试OK了,复杂的功能还待深入研究!发布出来一起探讨吧!
spring Scurity终于测试OK了,复杂的功能还待深入研究!发布出来一起探讨吧! 就是因 为研究它,我的个天啦!头都大了一圈!还待修改完整版!我的目标不是每个项目拿到它就能使用!到时再说啦.. ...
- IOS开发之格式化日期时间
IOS开发之格式化日期时间(转) 在开发iOS程序时,有时候需要将时间格式调整成自己希望的格式,这个时候我们可以用NSDateFormatter类来处理. 例如: //实例化一个NSDateFor ...
- 普通用户登录PLSQL后提示空白OK对话框错误
问题描述: 1.普通域账号登录域成员服务器后,打开PLSQL正常,输入用户名密码登录后提示一个空白的OK对话框,点确定后又返回到输入用户密码界面. 2.在CMD窗口下调用SQLPLUS登录数据库时报如 ...