public HandlerContext(Instructions block, TryInstructionHandler ilHandler, TryContext tryContext, TBBHandler tbbHandler) : base(block) { ILHandler = ilHandler; TryContext = tryContext; TBBHandler = tbbHandler; }
public bool HandleException(TryContext tryObject) { var ex = tryObject.LastException as T; exceptionHandler(ex); return(true); }
public int ComputeDelay(TryContext context) { if (context.FailedCount == 1) { return(InitialTimeout); } return(Timeout); }
public bool ComputeRepeat(TryContext context) { if (context.WaitedTime >= Limit) { return(false); } return(context.FailedCount < N); }
bool IExpectedExceptionHandler.HandleException(TryContext tryContext) { if (!(tryContext.LastException is T)) { return(false); } return(HandleException(tryContext.LastException as T, tryContext)); }
public int ComputeDelay(TryContext context) { var i = context.FailedCount; if (i == 1) { return(InitialTimeout); } return(i * i * Timeout); }
/// <summary> /// 列出指定组织的全部联系人 /// </summary> private static void ListAllContactAt() { Console.Clear(); Console.WriteLine("组织联系人列表"); var newO = new Organizer(); var newE = new Event(); using (var context = new TryContext()) { var olist = from oname in context.Organizers select oname; foreach (var o in olist) { Console.WriteLine("ID:" + o.OrganizerId + " Name:" + o.Name); } } Console.WriteLine("请参照上方列表输入要查询联系人的组织ID后按Enter"); var oId = Convert.ToInt16(Console.ReadLine()?.Trim()); var exists = CheckForExistingOrganizerId(oId); if (exists) { Console.Clear(); Console.WriteLine("活动列表"); using (var context = new TryContext()) { var clist = from c in context.Contacts join o in context.Organizers on c.OrganizerId equals o.OrganizerId where o.OrganizerId == oId select new { c.ContactId, c.Name, c.Phone, OrganizerName = o.Name }; foreach (var c in clist) { Console.WriteLine("ID:" + c.ContactId + " 组织方:" + c.OrganizerName + " 姓名:" + c.Name + " 电话:" + c.Phone); } } Console.WriteLine("\r\n按任意键继续..."); Console.ReadKey(); } else { Console.WriteLine("\r\n你输入的活动所属组织不存在,请重新输入\r\n按任意键继续..."); Console.ReadKey(); } }
/// <summary> /// 列出全部组织 /// </summary> public static void ListAllOrganizers() { Console.Clear(); Console.WriteLine("组织列表"); using (var context = new TryContext()) { var olist = from oname in context.Organizers select oname; foreach (var o in olist) { Console.WriteLine("ID:" + o.OrganizerId + " Name:" + o.Name); } } Console.WriteLine("\r\n按任意键继续..."); Console.ReadKey(); }
/// <summary> /// 检查输入的ID是否存在对应的组织 /// </summary> /// <param id="id"></param> /// <returns></returns> private static bool CheckForExistingOrganizerId(int Id) { var exists = false; using (var context = new TryContext()) { var oId = context.Organizers.Where(o => o.OrganizerId == Id); if (oId.Any()) { //if (oName.Count() > 0) 这个方法也可以,但是要注意捕捉异常 exists = true; } } return(exists); }
/// <summary> /// 检查输入的组织名是否存在对应的组织 /// </summary> /// <param name="name"></param> /// <returns></returns> private static bool CheckForExistingOrganizer(string name) { var exists = false; using (var context = new TryContext()) { var oName = context.Organizers.Where(o => o.Name == name); if (oName.Any()) { //if (oName.Count() > 0) 这个方法也可以,但是要注意捕捉异常 exists = true; } } return(exists); }
/// <summary> /// 添加指定组织的联系人 /// </summary> public static void AddContactWithOrganizer() { Console.Clear(); Console.WriteLine("组织列表"); var newO = new Organizer(); var newC = new Contact(); using (var context = new TryContext()) { var olist = from oname in context.Organizers select oname; foreach (var o in olist) { Console.WriteLine("ID:" + o.OrganizerId + " Name:" + o.Name); } } Console.WriteLine("请参照上方列表输入要创建联系人的组织ID后按Enter"); var oId = Convert.ToInt16(Console.ReadLine()?.Trim()); var exists = CheckForExistingOrganizerId(oId); if (exists) { Console.WriteLine("输入联系人姓名后按Enter"); var cName = Console.ReadLine(); Console.WriteLine("输入联系人电话后按Enter"); var cPhone = Console.ReadLine(); newC.Name = cName; newC.Phone = cPhone; newC.OrganizerId = oId; using (var context = new TryContext()) { Console.WriteLine("\r\n正在尝试保存..."); context.Contacts.Add(newC); var i = context.SaveChanges(); if (i == 1) { Console.WriteLine("添加联系人成功\r\n按任意键继续..."); Console.ReadKey(); } } } else { Console.WriteLine("\r\n你输入的组织不存在,请重新输入\r\n按任意键继续..."); Console.ReadKey(); } }
/// <summary> /// 列出指定组织的全部活动 /// </summary> private static void ListAllEventsAt() { Console.Clear(); Console.WriteLine("组织列表"); var newO = new Organizer(); var newE = new Event(); using (var context = new TryContext()) { var olist = from oname in context.Organizers select oname; foreach (var o in olist) { Console.WriteLine("ID:" + o.OrganizerId + " Name:" + o.Name); } } Console.WriteLine("请参照上方列表输入要创建活动的组织ID后按Enter"); var oId = Convert.ToInt16(Console.ReadLine()?.Trim()); var exists = CheckForExistingOrganizerId(oId); if (exists) { Console.Clear(); Console.WriteLine("活动列表"); using (var context = new TryContext()) { var elist = from o in context.Organizers from e in o.Events where o.OrganizerId == oId select e; foreach (var e in elist) { Console.WriteLine("ID:" + e.EventId + " Name:" + e.Name); } } Console.WriteLine("\r\n按任意键继续..."); Console.ReadKey(); } else { Console.WriteLine("\r\n你输入的活动所属组织不存在,请重新输入\r\n按任意键继续..."); Console.ReadKey(); } }
/// <summary> /// 添加指定组织的活动 /// </summary> public static void AddEventWithOrganizer() { Console.Clear(); Console.WriteLine("组织列表"); var newO = new Organizer(); var newE = new Event(); using (var context = new TryContext()) { var olist = from oname in context.Organizers select oname; foreach (var o in olist) { Console.WriteLine("ID:" + o.OrganizerId + " Name:" + o.Name); } } Console.WriteLine("请参照上方列表输入要创建活动的组织ID后按Enter"); var oId = Convert.ToInt16(Console.ReadLine()?.Trim()); var exists = CheckForExistingOrganizerId(oId); if (exists) { Console.WriteLine("输入活动名称后按Enter"); var eName = Console.ReadLine(); newE.Name = eName; newE.OrganizerId = oId; using (var context = new TryContext()) { Console.WriteLine("\r\n正在尝试保存..."); context.Events.Add(newE); var i = context.SaveChanges(); if (i == 1) { Console.WriteLine("添加活动成功\r\n按任意键继续..."); Console.ReadKey(); } } } else { Console.WriteLine("\r\n你输入的活动所属组织不存在,请重新输入\r\n按任意键继续..."); Console.ReadKey(); } }
/// <summary> /// 列出全部事件 /// </summary> public static void ListAllEvents() { Console.Clear(); Console.WriteLine("活动列表"); using (var context = new TryContext()) { var elist = from ename in context.Events join o in context.Organizers on ename.OrganizerId equals o.OrganizerId select new { ename.EventId, EventName = ename.Name, OrganizerName = o.Name }; foreach (var e in elist) { Console.WriteLine("ID:" + e.EventId + " Name:" + e.EventName + " 组织方:" + e.OrganizerName); } } Console.WriteLine("\r\n按任意键继续..."); Console.ReadKey(); }
/// <summary> /// 添加种子数据 /// </summary> private static void AddSeed() { Console.Clear(); Console.WriteLine("准备添加种子数据..."); using (var context = new TryContext()) { var org = new Organizer { Name = "胖才" }; context.Organizers.Add(org); var evt = new Event { Name = "扒蒜大赛" }; org.Events.Add(evt); var con = new Contact { Name = "江崟才" }; context.SaveChanges(); } Console.WriteLine("\r\n添加种子数据完成!"); Console.WriteLine("\r\n按任意键继续..."); Console.ReadKey(); }
/// <summary> /// 列出全部联系人 /// </summary> public static void ListAllContacts() { Console.Clear(); Console.WriteLine("联系人列表"); using (var context = new TryContext()) { //var clist = from c in context.Contacts // join o in context.Organizers on c.OrganizerId equals o.OrganizerId // select new // { // c.ContactId, // c.Name, // c.Phone, // OrganizerName = o.Name // }; //foreach (var c in clist) // Console.WriteLine("ID:" + c.ContactId + " 组织方:" + c.OrganizerName + " 姓名:" + c.Name + " 电话:" + c.Phone); var oList = from organizer in context.Organizers orderby organizer.Name select organizer; foreach (var o in oList) { Console.WriteLine(" 组织方:" + o.Name); using (var cContext = new TryContext()) { var cList = from c in cContext.Contacts where c.OrganizerId == o.OrganizerId select c; foreach (var c in cList) { Console.WriteLine("ID:" + c.ContactId + " 姓名:" + c.Name + " 电话:" + c.Phone); } } } } Console.WriteLine("\r\n按任意键继续..."); Console.ReadKey(); }
/// <summary> /// 添加组织 /// </summary> public static void AddOrganizer() { Console.Clear(); ConsoleKeyInfo cki; string result; var cont = false; var newO = new Organizer(); var oName = ""; WriteHeader("添加新组织"); Console.WriteLine("输入组织名称后按Enter"); oName = Console.ReadLine(); newO.Name = oName; var exists = CheckForExistingOrganizer(newO.Name); if (exists) { Console.WriteLine("\r\n你输入的组织已经存在,请重新输入\r\n按任意键继续..."); Console.ReadKey(); } else { using (var context = new TryContext()) { Console.WriteLine("\r\n正在尝试保存..."); context.Organizers.Add(newO); var i = context.SaveChanges(); if (i == 1) { Console.WriteLine("添加组织成功\r\n按任意键继续..."); Console.ReadKey(); } } } }
/// <summary> /// Run nullary computation in a safe context /// </summary> public static res Go <res>(this TryContext <res, Unit> that) => that.Go(Unit());
private BasicBlock BasicBlockFromIndex(int start, Context context) { if (start >= context.Block.Count) throw new InvalidOperationException("run off of end of instructions"); var offset = context.Block[start].Offset; var i = start; Func<int, Instructions> extractInclusive = j => context.Block.Peephole(start, j - start + 1, tracer); Func<int, Instructions> extractExclusive = j => context.Block.Peephole(start, j - start, tracer); while (i < context.Block.Count) { var instruction = context.Block[i]; if (i > start && targets.Contains(instruction.Offset)) { var jbb = new JumpBasicBlock(nextBlockId++, extractExclusive(i)); context.OffsetToBlock.Add(offset, jbb); jbb.Target = BasicBlockFromLocalTarget(instruction.Offset, context); jbb.Target.Sources.Add(jbb); return jbb; } else { switch (instruction.Flavor) { case InstructionFlavor.Misc: { var misci = (MiscInstruction)instruction; switch (misci.Op) { case MiscOp.Throw: { var nrbb = new NonReturningBasicBlock(nextBlockId++, extractInclusive(i)); context.OffsetToBlock.Add(offset, nrbb); return nrbb; } case MiscOp.Rethrow: { var handlerContext = context as HandlerContext; if (handlerContext == null || !(handlerContext.ILHandler is CatchTryInstructionHandler)) throw new InvalidOperationException("rethrow not within catch"); var nrbb = new NonReturningBasicBlock(nextBlockId++, extractInclusive(i)); context.OffsetToBlock.Add(offset, nrbb); return nrbb; } case MiscOp.Ret: case MiscOp.RetVal: { if (context is TryContext || context is HandlerContext) throw new InvalidOperationException("return within a try or handler block"); var nrbb = new NonReturningBasicBlock(nextBlockId++, extractInclusive(i)); context.OffsetToBlock.Add(offset, nrbb); return nrbb; } case MiscOp.Endfinally: { var handlerContext = context as HandlerContext; if (handlerContext == null) throw new InvalidOperationException ("endfinally not within fault/finally block"); switch (handlerContext.ILHandler.Flavor) { case HandlerFlavor.Catch: case HandlerFlavor.Filter: throw new InvalidOperationException ("endfinally not within fault/finally block"); case HandlerFlavor.Fault: { var efbb = new EndFaultBasicBlock (nextBlockId++, extractExclusive(i), (TBBFaultHandler)handlerContext.TBBHandler); context.OffsetToBlock.Add(offset, efbb); return efbb; } case HandlerFlavor.Finally: { var efbb = new EndFinallyBasicBlock (nextBlockId++, extractExclusive(i), (TBBFinallyHandler)handlerContext.TBBHandler, misci.BeforeState.Depth); context.OffsetToBlock.Add(offset, efbb); return efbb; } default: throw new ArgumentOutOfRangeException(); } } default: break; } break; } case InstructionFlavor.Branch: { var bri = (BranchInstruction)instruction; switch (bri.Op) { case BranchOp.Br: { var jbb = new JumpBasicBlock(nextBlockId++, extractExclusive(i)); context.OffsetToBlock.Add(offset, jbb); jbb.Target = BasicBlockFromLocalTarget(bri.Target, context); jbb.Target.Sources.Add(jbb); return jbb; } case BranchOp.Brtrue: case BranchOp.Brfalse: case BranchOp.Breq: case BranchOp.Brne: case BranchOp.BrLt: case BranchOp.BrLe: case BranchOp.BrGt: case BranchOp.BrGe: { if (i + 1 >= context.Block.Count) throw new InvalidOperationException("run off end of instructions"); var bbb = new BranchBasicBlock (nextBlockId++, extractExclusive(i), Test.FromBranchOp(bri.Op, bri.IsUnsigned, bri.Type)); context.OffsetToBlock.Add(offset, bbb); bbb.Target = BasicBlockFromLocalTarget(bri.Target, context); bbb.Target.Sources.Add(bbb); bbb.Fallthrough = BasicBlockFromLocalTarget(context.Block[i + 1].Offset, context); if (!bbb.Fallthrough.Equals(bbb.Target)) bbb.Fallthrough.Sources.Add(bbb); return bbb; } case BranchOp.Leave: { var handlerPopCount = default(int); var stackPopCount = bri.BeforeState.Depth; var leftContext = default(bool); var bb = BasicBlockFromTarget (bri.Target, context, out leftContext, out handlerPopCount); if (!leftContext) { // Not leaving try or handler block, so just empty stack and branch var lbb = new LeaveBasicBlock (nextBlockId++, extractExclusive(i), stackPopCount); context.OffsetToBlock.Add(offset, lbb); lbb.Target = bb; lbb.Target.Sources.Add(lbb); return lbb; } else { var tryContext = context as TryContext; if (tryContext != null) { // Poping at least one exception handler and branching var ltbb = new LeaveTryBasicBlock (nextBlockId++, extractExclusive(i), tryContext.TryBasicBlock, handlerPopCount, stackPopCount); context.OffsetToBlock.Add(offset, ltbb); ltbb.Target = bb; ltbb.Target.Sources.Add(ltbb); return ltbb; } else { var handlerContext = context as HandlerContext; if (handlerContext != null) { switch (handlerContext.ILHandler.Flavor) { case HandlerFlavor.Catch: { // Poping zero or more exception handlers and branching var lcbb = new LeaveCatchBasicBlock (nextBlockId++, extractExclusive(i), (TBBCatchHandler)handlerContext.TBBHandler, handlerPopCount, stackPopCount); lcbb.Target = bb; lcbb.Target.Sources.Add(lcbb); return lcbb; } case HandlerFlavor.Filter: throw new NotSupportedException("filter"); case HandlerFlavor.Fault: throw new InvalidOperationException("leaving fault block"); case HandlerFlavor.Finally: throw new InvalidOperationException("leaving finally block"); default: throw new ArgumentOutOfRangeException(); } } else throw new InvalidOperationException ("no try or handler context to leave"); } } } default: throw new ArgumentOutOfRangeException(); } } case InstructionFlavor.Switch: { if (i + 1 >= context.Block.Count) throw new InvalidOperationException("run off end of instructions"); var switchi = (SwitchInstruction)instruction; var sbb = new SwitchBasicBlock(nextBlockId++, extractExclusive(i)); context.OffsetToBlock.Add(offset, sbb); var seen = new Set<BasicBlock>(); foreach (var t in switchi.CaseTargets) { var target = BasicBlockFromLocalTarget(t, context); sbb.CaseTargets.Add(target); if (!seen.Contains(target)) { target.Sources.Add(sbb); seen.Add(target); } } sbb.Fallthrough = BasicBlockFromLocalTarget(context.Block[i + 1].Offset, context); if (!seen.Contains(sbb.Fallthrough)) sbb.Fallthrough.Sources.Add(sbb); return sbb; } case InstructionFlavor.Try: { // Try is known to be a target, thus i == start and extract(i) would yield empty var tryi = (TryInstruction)instruction; var parent = default(TryBasicBlock); var tryContext = context as TryContext; if (tryContext != null) parent = tryContext.TryBasicBlock; else { var handlerContext = context as HandlerContext; if (handlerContext != null) parent = handlerContext.TryContext.TryBasicBlock; } var tbb = new TryBasicBlock(nextBlockId++, parent, instruction.BeforeState); context.OffsetToBlock.Add(offset, tbb); var subTryContext = new TryContext(tryi.Body, context, tbb); tbb.Body = BasicBlockFromInstructions(subTryContext); tbb.Body.Sources.Add(tbb); foreach (var ilHandler in tryi.Handlers) { var tbbHandler = default(TBBHandler); switch (ilHandler.Flavor) { case HandlerFlavor.Catch: { var catchh = (CatchTryInstructionHandler)ilHandler; tbbHandler = new TBBCatchHandler(tbb, catchh.Type); break; } case HandlerFlavor.Filter: throw new NotSupportedException("filter blocks"); case HandlerFlavor.Fault: { tbbHandler = new TBBFaultHandler(tbb); break; } case HandlerFlavor.Finally: { tbbHandler = new TBBFinallyHandler(tbb); break; } default: throw new ArgumentOutOfRangeException(); } var subHandlerContext = new HandlerContext (ilHandler.Body, ilHandler, subTryContext, tbbHandler); tbbHandler.Body = BasicBlockFromInstructions(subHandlerContext); tbbHandler.Body.Sources.Add(tbb); tbb.Handlers.Add(tbbHandler); } return tbb; } default: break; } i++; } } throw new InvalidOperationException("ran off of end of instructions"); }
public bool ComputeRepeat(TryContext context) { return(context.FailedCount < N); }
protected override bool HandleException(T exception, TryContext tryContext) { return(true); }
protected abstract bool HandleException(T exception, TryContext tryContext);