ReaderWriterLockSlim
是 .NET Framework 提供的一種同步機制,用於管理對共享資源的訪問。它允許多個讀取者同時訪問資源,但只允許一個寫入者訪問資源。這有助於提高效能,特別是當有大量讀取操作時。
在這段程式碼中,ReaderWriterLockSlim
用於控制對 actionQueue
佇列的訪問。它確保在寫入(新增動作)時,不會有其他執行緒正在讀取或寫入。同時,在讀取(執行動作)時,其他執行緒可以繼續讀取,但不允許進行寫入。
另外,ReaderWriterLockSlim
實現了 IDisposable
介面,這意味著它具有釋放資源的能力。
在Unity中使用一個 MonoBehaviour, Singleten, DontDestroyOnLoad 的static Instance,來 管理多線呈 的 回調Action 的 執行順序,確保每一次Unity Update更新只跑一個回調。
在程式碼的 OnDestroy
方法中,lockSlim.Dispose()
被呼叫,這用於釋放 ReaderWriterLockSlim
所佔用的資源,以避免資源洩漏或占用過多的記憶體。
這個技術用在多人聯機的Server更新部分。
private ReaderWriterLockSlim lockSlim = new ReaderWriterLockSlim();
private Queue<Action> actionQueue = new Queue<Action>();
internal Action SyncCallback( Action listener ) {
return () => EnqueueAction( () => listener.Invoke() );
}
internal Action<object> SyncCallback( Action<object> listener ) {
return ( object obj ) => EnqueueAction( () => listener.Invoke( obj ) );
}
internal Action<User> SyncCallback( Action<User> listener ) {
return ( User user ) => EnqueueAction( () => listener.Invoke( user ) );
}
internal Action<string, object> SyncCallback( Action<string, object> listener ) {
return ( string eventName, object obj ) => EnqueueAction( () => listener.Invoke( eventName, obj ) );
}
internal Action<string, object[]> SyncCallback( Action<string, object[]> listener ) {
return ( string eventName, object[] args ) => EnqueueAction( () => listener.Invoke( eventName, args ) );
}
internal Action<T1> SyncCallback<T1>( Action<T1> listener ) {
return ( T1 arg1 ) => EnqueueAction( () => listener.Invoke( arg1 ) );
}
internal Action<T1, T2> SyncCallback<T1, T2>( Action<T1, T2> listener ) {
return ( T1 arg1, T2 arg2 ) => EnqueueAction( () => listener.Invoke( arg1, arg2 ) );
}
internal Action<T1, T2, T3> SyncCallback<T1, T2, T3>( Action<T1, T2, T3> listener ) {
return ( T1 arg1, T2 arg2, T3 arg3 ) => EnqueueAction( () => listener.Invoke( arg1, arg2, arg3 ) );
}
internal Action<T1, T2, T3, T4> SyncCallback<T1, T2, T3, T4>( Action<T1, T2, T3, T4> listener ) {
return ( T1 arg1, T2 arg2, T3 arg3, T4 arg4 ) => EnqueueAction( () => listener.Invoke( arg1, arg2, arg3, arg4 ) );
}
internal Action<T1, T2, T3, T4, T5> SyncCallback<T1, T2, T3, T4, T5>( Action<T1, T2, T3, T4, T5> listener ) {
return ( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5 ) => EnqueueAction( () => listener.Invoke( arg1, arg2, arg3, arg4, arg5 ) );
}
private void EnqueueAction( Action action ) {
try {
lockSlim.EnterWriteLock();
actionQueue.Enqueue( action );
}
finally {
lockSlim.ExitWriteLock();
}
}
private void OnDestroy() {
lockSlim.Dispose();
}