异步编程设计模式 - 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,对开发者并不透明 代码设计模式 异步编程有很多特有的代码设计模式,为了实现同样的功能,使用同步方式和异步方式编写代码会有很大 ...
随机推荐
- Java并发编程--线程封闭(Ad-hoc封闭 栈封闭 ThreadLocal)
线程封闭实现好的并发是一件困难的事情,所以很多时候我们都想躲避并发.避免并发最简单的方法就是线程封闭.什么是线程封闭呢?就是把对象封装到一个线程里,只有这一个线程能看到此对象.那么这个对象就算不是线程 ...
- IOS NSURL基本操作-备
NSURL其实就是我们在浏览器上看到的网站地址,这不就是一个字符串么,为什么还要在写一个NSURL呢,主要是因为网站地址的字符串都比较复杂,包括很多请求参数,这样在请求过程中需要解析出来每个部门,所以 ...
- 创建一个自己的动态HTML-备
-.获取元素 改变属性 通过id来获取HTML元素 通过标签名找到HTML元素 通过类名来找到HTML元素 举个
- IOS 解析歌词lrc
最近在捣鼓音乐播放器,过程中学到了一些东西,写下来分享一下,首先是歌词的解析 首先我们看看lrc(不贴维基了怕打不开 歌词文件一般是这样的格式 1.[分钟:秒.毫秒] 歌词 2. [分钟:秒] 歌词 ...
- Effective Java实作Comparator - 就是爱Java
如果集合或数组内的对象,有1个以上不同的排序逻辑时,那该如何处理呢?尤其是当已经实现了Comparable,又不能变动原本的逻辑时,Mix会采用Comparator来处理. 阅读全文>>
- LeetCode_Unique Paths
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...
- 自制单片机之七……扩展:DS18B20温度测量
DS18B20数字温度测量传感器,网上介绍很多,我就不罗嗦了.见图 DS18B20与前产品DS1820的不同: DS18B20继承了DS1820的全部优点,并做了如下改进 1.供电范围扩大为3.0-- ...
- Java并发实现一(并发的实现之Thread和Runnable的区别)
package com.subject01; public class ThreadOrRunnable { public static void main(String[] args) { Syst ...
- mongodb 更新数组出现can't append to array using string field name
数据库内容大概如下: { _id:, "hero_list" : { " : { , , "equip" : [ [ ], [ ], [ ], { , ...
- UVA 10400 Game Show Math (dfs + 记忆化搜索)
Problem H Game Show Math Input: standard input Output: standard output Time Limit: 15 seconds A game ...