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. 后台管理UI

    后台管理UI 目录 一.EasyUI 二.DWZ JUI 三.HUI 四.BUI 五.Ace Admin 六.Metronic 七.H+ UI 八.Admin LTE 九.INSPINIA 十.Lig ...

  2. nodejs安装express遇到的坑

    网上很多资料都是npm install express -g; 安装完也不报错,但使用express的时候却报找不到命令: 在网上查了好多,最后用 npm install -g express-gen ...

  3. 关于开源中文搜索引擎架构coreseek中算法详解

     Coreseek 是一款中文全文检索/搜索软件,以GPLv2许可协议开源发布,基于Sphinx研发并独立发布,专攻中文搜索和信息处理领域,适用于行业/垂直搜索.论坛/站内搜索.数据库搜索.文档/文献 ...

  4. android slidingview

    http://blog.csdn.net/sky181772733/article/details/6969810 http://blog.csdn.net/ithomer/article/detai ...

  5. 转:什么是CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI?

    什么是CGI CGI全称是“公共网关接口”(Common Gateway Interface),HTTP服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上. CGI可以用 ...

  6. 【转】如何过滤 adb logcat 输出

    原文网址:http://www.cnblogs.com/imouto/archive/2012/12/11/filtering-adb-logcat-output.html 简介: 本文介绍如何在 s ...

  7. Codeforces Round #272 (Div. 1) Problem C. Dreamoon and Strings

    C. Dreamoon and Strings time limit per test 1 second memory limit per test 256 megabytes input stand ...

  8. Java Web----Java Web的数据库操作(一)

    Java Web的数据库操作 一.JDBC技术 1.JDBC简介 JDBC是Java程序与数据库系统通信的标准API,它定义在JDK的API中,通过JDBC技术,Java程序可以非常方便地与各种数据库 ...

  9. Apache+php配置 Mysql安装出错解决办法

    此文包括的注意内容:软件版本及下载地址Apache2.4的配置和安装php7.0的配置mysql5.5的安装常见问题及解决方法1.软件版本Windows server 2008 r2+ 64位Apac ...

  10. jQuery 各种选择器 $.()用法

    jQuery 元素选择器jQuery 使用 CSS 选择器来选取 HTML 元素. $("p") 选取 <p> 元素. $("p.intro") 选 ...