annotate Source/Aspects/Builders/AsyncAspectBuilder.cs @ 3:1ef98bd70424

!bug 100 +3h Исправление проблемы BLToolkit + mono 3.4
author cin
date Fri, 22 Aug 2014 17:34:46 +0400
parents f990fcb411a9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1 using System;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2 using System.Reflection;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
3 using System.Threading;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
4
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
5 namespace BLToolkit.Aspects.Builders
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
6 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
7 using Properties;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
8 using TypeBuilder;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
9 using TypeBuilder.Builders;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
10
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
11 /// <summary>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
12 /// This aspect simplifies asynchronous operations.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
13 /// </summary>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
14 public class AsyncAspectBuilder : AbstractTypeBuilderBase
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
15 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
16 private readonly string _targetMethodName;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
17 private readonly Type[] _parameterTypes;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
18
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
19 public AsyncAspectBuilder(string targetMethodName, Type[] parameterTypes)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
20 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
21 _targetMethodName = targetMethodName;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
22 _parameterTypes = parameterTypes;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
23 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
24
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
25 public override int GetPriority(BuildContext context)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
26 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
27 return TypeBuilderConsts.Priority.AsyncAspect;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
28 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
29
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
30 public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
31 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
32 if (context.IsBuildStep)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
33 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
34
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
35 var list = new AbstractTypeBuilderList(2) { this, typeBuilder };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
36 var step = context.Step;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
37
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
38 try
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
39 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
40 context.Step = BuildStep.Build;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
41
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
42 return typeBuilder.IsApplied(context, list);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
43 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
44 finally
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
45 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
46 context.Step = step;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
47 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
48 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
49
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
50 public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
51 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
52 if (context == null) throw new ArgumentNullException("context");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
53
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
54 return context.IsBuildStep && context.BuildElement == BuildElement.AbstractMethod;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
55 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
56
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
57 protected override void BuildAbstractMethod()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
58 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
59 var mi = Context.CurrentMethod;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
60
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
61 if (mi.ReturnType == typeof(IAsyncResult))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
62 BuildBeginMethod();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
63 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
64 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
65 var parameters = mi.GetParameters();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
66
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
67 if (parameters.Length == 1 && parameters[0].ParameterType == typeof(IAsyncResult))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
68 BuildEndMethod();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
69 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
70 throw new TypeBuilderException(string.Format("Method '{0}.{1}' is not a 'Begin' nor an 'End' method.", mi.DeclaringType.FullName, mi.Name));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
71 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
72 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
73
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
74 private void BuildBeginMethod()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
75 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
76 var mi = Context.CurrentMethod;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
77 var method = GetTargetMethod(Context, "Begin");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
78 var delegateType = EnsureDelegateType(Context, method);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
79 var emit = Context.MethodBuilder.Emitter;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
80 var type = typeof(InternalAsyncResult);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
81 var arLocal = emit.DeclareLocal(type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
82 var dLocal = emit.DeclareLocal(delegateType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
83
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
84 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
85 .newobj (type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
86 .dup
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
87 .dup
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
88 .dup
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
89 .stloc (arLocal)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
90 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
91 .ldftn (method)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
92 .newobj (delegateType, typeof(object), typeof(IntPtr))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
93 .stloc (dLocal)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
94 .ldloc (dLocal)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
95 .stfld (type.GetField("Delegate"))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
96 .ldloc (dLocal)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
97 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
98
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
99 var callbackIndex = -1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
100 var parameters = mi.GetParameters();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
101
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
102 for (var i = 0; i < parameters.Length; ++i)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
103 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
104 if (parameters[i].ParameterType == typeof(AsyncCallback))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
105 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
106 callbackIndex = i;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
107 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
108 .ldloc (arLocal)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
109 .dup
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
110 .ldarg (parameters[i])
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
111 .stfld (type.GetField("AsyncCallback"))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
112 .ldftn (type.GetMethod("CallBack"))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
113 .newobj (typeof(AsyncCallback), typeof(object), typeof(IntPtr))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
114 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
115 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
116 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
117 emit.ldarg(parameters[i]);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
118 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
119
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
120 if (callbackIndex < 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
121 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
122 // Callback omitted
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
123 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
124 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
125 .ldnull
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
126 .ldnull
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
127 .end();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
128 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
129 else if (callbackIndex == parameters.Length - 1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
130 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
131 // State omitted
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
132 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
133 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
134 .ldnull
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
135 .end();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
136 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
137
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
138 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
139 .callvirt (delegateType.GetMethod("BeginInvoke"))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
140 .stfld (type.GetField("InnerResult"))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
141 .stloc (Context.ReturnValue)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
142 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
143 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
144
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
145 private void BuildEndMethod()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
146 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
147 var method = GetTargetMethod(Context, "End");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
148 var delegateType = EnsureDelegateType(Context, method);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
149 var emit = Context.MethodBuilder.Emitter;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
150 var type = typeof(InternalAsyncResult);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
151 var arLocal = emit.DeclareLocal(type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
152
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
153 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
154 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
155 .castclass (type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
156 .dup
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
157 .stloc (arLocal)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
158 .ldfld (type.GetField("Delegate"))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
159 .castclass (delegateType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
160 .ldloc (arLocal)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
161 .ldfld (type.GetField("InnerResult"))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
162 .callvirt (delegateType, "EndInvoke", typeof(IAsyncResult));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
163
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
164 if (Context.ReturnValue != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
165 emit.stloc(Context.ReturnValue);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
166 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
167
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
168 private MethodInfo GetTargetMethod(BuildContext context, string prefix)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
169 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
170 var targetMethodName = _targetMethodName;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
171
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
172 if (targetMethodName == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
173 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
174 var mi = context.CurrentMethod;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
175 var name = mi.Name;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
176
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
177 if (name.StartsWith(prefix))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
178 targetMethodName = name.Substring(prefix.Length);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
179 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
180 throw new TypeBuilderException(string.Format(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
181 Resources.AsyncAspectBuilder_NoTargetMethod,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
182 mi.DeclaringType.FullName, mi.Name));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
183 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
184
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
185 return _parameterTypes == null?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
186 context.Type.GetMethod(targetMethodName):
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
187 context.Type.GetMethod(targetMethodName, _parameterTypes);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
188 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
189
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
190 private static Type EnsureDelegateType(BuildContext context, MethodInfo method)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
191 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
192 // The delegate should be defined as inner type of context.TypeBuilder.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
193 // It's possible, but we can not define and use newly defined type as Emit target in its owner type.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
194 // To solve this problem, we should create a top level delegate and make sure its name is unique.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
195 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
196 var delegateName = context.TypeBuilder.TypeBuilder.FullName + "$" + method.Name + "$Delegate";
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
197 var delegateType = context.GetItem<Type>(delegateName);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
198
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
199 if (delegateType == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
200 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
201 var pi = method.GetParameters();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
202 var parameters = new Type[pi.Length];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
203
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
204 for (var i = 0; i < pi.Length; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
205 parameters[i] = pi[i].ParameterType;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
206
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
207 const MethodImplAttributes mia = MethodImplAttributes.Runtime | MethodImplAttributes.Managed;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
208 const MethodAttributes ma = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
209
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
210 var delegateBuilder = context.AssemblyBuilder.DefineType(delegateName,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
211 TypeAttributes.Class | TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
212 typeof(MulticastDelegate));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
213
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
214 // Create constructor
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
215 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
216 var ctorBuilder = delegateBuilder.DefineConstructor(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
217 MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName, CallingConventions.Standard,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
218 typeof(object), typeof(IntPtr));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
219 ctorBuilder.ConstructorBuilder.SetImplementationFlags(mia);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
220
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
221 // Define the BeginInvoke method for the delegate
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
222 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
223 var beginParameters = new Type[parameters.Length + 2];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
224
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
225 Array.Copy(parameters, 0, beginParameters, 0, parameters.Length);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
226 beginParameters[parameters.Length] = typeof(AsyncCallback);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
227 beginParameters[parameters.Length+1] = typeof(object);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
228
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
229 var methodBuilder = delegateBuilder.DefineMethod("BeginInvoke", ma, typeof(IAsyncResult), beginParameters);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
230
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
231 methodBuilder.MethodBuilder.SetImplementationFlags(mia);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
232
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
233 // Define the EndInvoke method for the delegate
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
234 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
235 methodBuilder = delegateBuilder.DefineMethod("EndInvoke", ma, method.ReturnType, typeof(IAsyncResult));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
236 methodBuilder.MethodBuilder.SetImplementationFlags(mia);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
237
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
238 // Define the Invoke method for the delegate
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
239 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
240 methodBuilder = delegateBuilder.DefineMethod("Invoke", ma, method.ReturnType, parameters);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
241 methodBuilder.MethodBuilder.SetImplementationFlags(mia);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
242
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
243 context.Items.Add(delegateName, delegateType = delegateBuilder.Create());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
244 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
245
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
246 return delegateType;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
247 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
248
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
249 #region Helper
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
250
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
251 /// <summary>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
252 /// Reserved for internal BLToolkit use.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
253 /// </summary>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
254 public class InternalAsyncResult : IAsyncResult
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
255 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
256 public IAsyncResult InnerResult;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
257 public Delegate Delegate;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
258 public AsyncCallback AsyncCallback;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
259
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
260 public void CallBack(IAsyncResult ar)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
261 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
262 if (AsyncCallback != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
263 AsyncCallback(this);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
264 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
265
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
266 public bool IsCompleted { get { return InnerResult.IsCompleted; } }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
267 public WaitHandle AsyncWaitHandle { get { return InnerResult.AsyncWaitHandle; } }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
268 public object AsyncState { get { return InnerResult.AsyncState; } }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
269 public bool CompletedSynchronously { get { return InnerResult.CompletedSynchronously; } }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
270 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
271
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
272 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
273 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
274 }