UH4L12——协同程序和异步函数
协同程序和异步函数
之所以需要注册跨域继承适配器,是因为在ILRuntime中的协同程序和异步函数
编译后本质上是通过状态机利用对象的状态来达到的异步,这里面的对象就用到了跨域继承
所以我们需要注册他们的跨域继承适配器来让热更新工程正常使用他们
在ILRuntime热更工程中使用协同程序
如果不注册就直接在热更工程内开启协程,会报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class ILRuntimeMain { public static void Main() { Lesson16 lesson16 = Camera.main.GetComponent<Lesson16>(); lesson16.StartCoroutine(Lesson16Test()); }
public static IEnumerator Lesson16Test() { Debug.Log(0); yield return new WaitForSeconds(1f); Debug.Log(1); yield return new WaitForSeconds(1f); Debug.Log(2); yield return new WaitForSeconds(1f); Debug.Log(3); } }
|
需要注册 协同程序的 跨域继承适配器,可以在示例工程中获取
然后,在appDomain加载完dll和pdb文件后的初始化逻辑中加上对CoroutineAdapter
的跨域继承注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| private unsafe void InitILRuntime() { appDomain.RegisterCrossBindingAdaptor(new ILRuntimeAdapter.Lesson11_TestAdapter()); appDomain.RegisterCrossBindingAdaptor(new CoroutineAdapter()); appDomain.RegisterValueTypeBinder(typeof(Vector3), new Vector3Binder()); appDomain.RegisterValueTypeBinder(typeof(Vector2), new Vector2Binder()); appDomain.RegisterValueTypeBinder(typeof(Quaternion), new QuaternionBinder());
System.Type debugType = typeof(Debug); MethodInfo methodInfo = debugType.GetMethod("Log", new System.Type[] { typeof(object) }); appDomain.RegisterCLRMethodRedirection(methodInfo, MyLog);
ILRuntime.Runtime.Generated.CLRBindings.Initialize(appDomain); appDomain.UnityMainThreadID = Thread.CurrentThread.ManagedThreadId; }
|
输出:
在ILRuntime热更工程中使用异步函数
注册 异步函数的 跨域继承适配器,可以获取别人写好的异步函数跨域适配器:
jumpst.github.io/IAsyncStateMachineClassInheritanceAdaptor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| using System; using ILRuntime.CLR.Method; using ILRuntime.Runtime.Enviorment; using ILRuntime.Runtime.Intepreter;
namespace ILRuntimeTest.TestFramework { public class IAsyncStateMachineClassInheritanceAdaptor : CrossBindingAdaptor { public override Type BaseCLRType { get { return typeof(System.Runtime.CompilerServices.IAsyncStateMachine); } }
public override Type AdaptorType { get { return typeof(IAsyncStateMachineAdaptor); } }
public override object CreateCLRInstance(ILRuntime.Runtime.Enviorment.AppDomain appdomain, ILTypeInstance instance) { return new IAsyncStateMachineAdaptor(appdomain, instance); }
public class IAsyncStateMachineAdaptor : System.Runtime.CompilerServices.IAsyncStateMachine, CrossBindingAdaptorType { ILTypeInstance instance; ILRuntime.Runtime.Enviorment.AppDomain appdomain; CrossBindingMethodInfo mMoveNext_0 = new CrossBindingMethodInfo("MoveNext"); CrossBindingMethodInfo<System.Runtime.CompilerServices.IAsyncStateMachine> mSetStateMachine_1 = new CrossBindingMethodInfo<System.Runtime.CompilerServices.IAsyncStateMachine>("SetStateMachine");
public IAsyncStateMachineAdaptor() {
}
public IAsyncStateMachineAdaptor(ILRuntime.Runtime.Enviorment.AppDomain appdomain, ILTypeInstance instance) { this.appdomain = appdomain; this.instance = instance; }
public ILTypeInstance ILInstance { get { return instance; } }
public void MoveNext() { mMoveNext_0.Invoke(this.instance); }
public void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine stateMachine) { mSetStateMachine_1.Invoke(this.instance, stateMachine); }
public override string ToString() { IMethod m = appdomain.ObjectType.GetMethod("ToString", 0); m = instance.Type.GetVirtualMethod(m); if (m == null || m is ILMethod) { return instance.ToString(); } else return instance.Type.FullName; } } } }
|
在热更工程内执行异步方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class ILRuntimeMain { public static void Main() { Lesson16Test2(); }
public static async void Lesson16Test2() { Debug.Log(0); await Task.Delay(1000); Debug.Log(1); await Task.Delay(1000); Debug.Log(2); await Task.Delay(1000); Debug.Log(3); } }
|
如果不提前注册,直接调用同样会报错,因此同样需要在appDomain
加载完dll和pdb文件后的初始化逻辑中
加上对IAsyncStateMachineClassInheritanceAdaptor
的跨域继承注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| private unsafe void InitILRuntime() { appDomain.RegisterCrossBindingAdaptor(new ILRuntimeAdapter.Lesson11_TestAdapter()); appDomain.RegisterCrossBindingAdaptor(new CoroutineAdapter()); appDomain.RegisterCrossBindingAdaptor(new IAsyncStateMachineClassInheritanceAdaptor()); appDomain.RegisterValueTypeBinder(typeof(Vector3), new Vector3Binder()); appDomain.RegisterValueTypeBinder(typeof(Vector2), new Vector2Binder()); appDomain.RegisterValueTypeBinder(typeof(Quaternion), new QuaternionBinder());
System.Type debugType = typeof(Debug); MethodInfo methodInfo = debugType.GetMethod("Log", new System.Type[] { typeof(object) }); appDomain.RegisterCLRMethodRedirection(methodInfo, MyLog);
ILRuntime.Runtime.Generated.CLRBindings.Initialize(appDomain); appDomain.UnityMainThreadID = Thread.CurrentThread.ManagedThreadId; }
|
输出: