### Implementing Actor Entry Queuing Transparency in C# Source: https://github.com/gameframex/gameframex.server/blob/main/README.md Explains how GameFrameX automatically generates wrapper classes to handle Actor method queuing using SendAsync, allowing developers to call Actor methods like regular functions without worrying about multi-threading or queuing logic. Shows examples of wrapping methods like CheckCrossDay and GetDaysFromOpenServer. ```C# //编译期间会注入一个继承自xxxCompAgent的wrapper类,来实现自动入队 //同时SendAsync内部自动处理了线程上下文,开发者只需要像调用普通函数一样书写逻辑 public class ServerComponentAgentWrapper : ServerComponentAgent { public override Task CheckCrossDay() { return base.Actor.SendAsync((Func)base.CheckCrossDay, isAwait: false, 10000); } public override Task GetDaysFromOpenServer() { return base.Actor.SendAsync((Func>)base.GetDaysFromOpenServer, isAwait: true, 10000); } } var serverComp = await EntityMgr.GetCompAgent(ActorType.Server); //使用方式(就像调用普通函数一样,无需关心多线程或入队) _ = serverComp.CheckCrossDay(); ``` -------------------------------- ### Illustrating Potential Actor Deadlock Scenario in C# Source: https://github.com/gameframex/gameframex.server/blob/main/README.md Provides a code example demonstrating a multi-way deadlock scenario in an Actor system. It shows how two Actors, ActorA and ActorB, can enter a deadlock state if ActorA calls ActorB and ActorB simultaneously calls ActorA, and both calls involve waiting (await). The Call method shows how this scenario can be initiated. ```csharp class ActorA { Task A1() { await Task.Delay(10); var b = GetActorB(); return b.SendAsync(b.B1); } Task A2() { var b = GetActorB(); return b.SendAsync(b.B1); } } class ActorB { Task B1() { await Task.Delay(5); var a = GetActorA(); return a.SendAsync(a.A2); } } Task Call() { var a = GetActorA(); return a.SendAsync(a.A1);//这里就会触发死锁 } ``` -------------------------------- ### Managing Thread Context with RuntimeContext in C# Source: https://github.com/gameframex/gameframex.server/blob/main/README.md Demonstrates the RuntimeContext class used internally by GameFrameX to manage thread context. It utilizes AsyncLocal to track the current call chain ID, enabling features like circular call detection and determining the need for Actor queuing. Includes methods for setting and resetting the context. ```C# internal class RuntimeContext { internal static long Current => callCtx.Value; internal static AsyncLocal callCtx = new AsyncLocal(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void SetContext(long callChainId) { callCtx.Value = callChainId; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void ResetContext() { callCtx.Value = 0; } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.