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的更多相关文章

  1. 异步编程设计模式Demo - AsyncComponentSample

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.C ...

  2. 异步编程设计模式Demo - PrimeNumberCalculator

    using System; using System.Collections; using System.Collections.Specialized; using System.Component ...

  3. [.net 多线程]异步编程模式

    .NET中的异步编程 - EAP/APM 从.NET 4.5开始,支持的三种异步编程模式: 基于事件的异步编程设计模式 (EAP,Event-based Asynchronous Pattern) 异 ...

  4. JavaScript异步编程的主要解决方案—对不起,我和你不在同一个频率上

    众所周知(这也忒夸张了吧?),Javascript通过事件驱动机制,在单线程模型下,以异步的形式来实现非阻塞的IO操作.这种模式使得JavaScript在处理事务时非常高效,但这带来了很多问题,比如异 ...

  5. C#基础系列——异步编程初探:async和await

    前言:前面有篇从应用层面上面介绍了下多线程的几种用法,有博友就说到了async, await等新语法.确实,没有异步的多线程是单调的.乏味的,async和await是出现在C#5.0之后,它的出现给了 ...

  6. C#编程总结(六)异步编程

    C#编程总结(六)异步编程 1.什么是异步? 异步操作通常用于执行完成时间可能较长的任务,如打开大文件.连接远程计算机或查询数据库.异步操作在主应用程序线程以外的线程中执行.应用程序调用方法异步执行某 ...

  7. node.js整理 06异步编程

    回调 异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了 function heavyCompute(n, callback) { var count = 0, i, j; for (i = ...

  8. 你所必须掌握的三种异步编程方法callbacks,listeners,promise

    目录: 前言 Callbacks Listeners Promise 前言 coder都知道,javascript语言运行环境是单线程的,这意味着任何两行代码都不能同时运行.多任务同时进行时,实质上形 ...

  9. NodeJS学习之异步编程

    NodeJS -- 异步编程 NodeJS最大的卖点--事件机制和异步IO,对开发者并不透明 代码设计模式 异步编程有很多特有的代码设计模式,为了实现同样的功能,使用同步方式和异步方式编写代码会有很大 ...

随机推荐

  1. iphone 拨打电话的 两种方法-备

    大家想不想在自己的应用中拨打电话呀?打电话可以用openURL:这个API, 如:[[UIApplication sharedApplication] openURL:[NSURL URLWithSt ...

  2. QuickReport多页打印

    You use composite reports for this(TQrCompositeReport) on the quickreports tabTake a look in the Dem ...

  3. ASP.NET WEB API回发到客户端消息体的格式化

    首先基于SOA的消息通信基本都是按照一个统一的协议规范进行交互,那么必须定义消息体.不同的交互结构设计了不同的消息体. 业界统一使用的SOAP是一种规范的XML消息内容.例如在WCF中返回的结果. 随 ...

  4. Linux企业级项目实践之网络爬虫(12)——处理HTTP应答头

    Web服务器的HTTP应答一般由以下几项构成:一个状态行,一个或多个应答头,一个空行,内容文档.设置HTTP应答头往往和设置状态行中的状态代码结合起来.例如,有好几个表示"文档位置已经改变& ...

  5. dp优化简单总结

    1.二分优化 (使用二分查找优化查找效率) 典型例题:LIS dp[i]保存长度为 i 的上升子序列中最小的结尾,可以用二分查找优化到nlogn 2.数学优化 (通过数学结论减少状态数) 例题1:hd ...

  6. Activity小结

    Log日志类的五种级别 1.由高到低分别是:v.i.d.w.e 2.生命周期有七种状态: onCreate:创建 onStart:启动 onResume:显示(可以与用户交互) onPause:暂停 ...

  7. poj 1274 The Perfect Stall(二分图匹配)

    Description Farmer John completed his new barn just last week, complete with all the latest milking ...

  8. html5 750 REM JS换算方法

    在安卓手机低版本浏览器,如果进页面快速执行的话会出现计算宽度不正确的情况,解决方法是放在onload方法里面执行,但这种解决方式在一些高版本浏览器中会出现页面闪动,所以使用判断浏览器版本的方式来解决, ...

  9. bootstrap学习以及其插件

    Bootstrap中文网地址,里面有bootstrap组件的下载与使用说明,现在使用bootstrap3: http://www.bootcss.com/ W3CSchool.CC里面有学习boots ...

  10. 【编程范式】汇编解释swap方法

    先要熟悉一些汇编的基本知识: 1.SP是什么? SP是堆栈寄存器,在调用子程序时,都会用到,保存原来程序的环境使用,如各个寄存器的内容,最重要的是,调用返回时程序的运行指令地址,这是由调用时将返回地址 ...