UnregisterAllEvents does not work
Closed this issue · 0 comments
steven4547466 commented
- Register some events
- Try to use
UnregisterAllEvents(object plugin)
, and it will never complete.
Example:
Log.Info("Unregistering events");
EventManager.UnregisterAllEvents(this);
Log.Info("Done");
"Done" will never print and you may or may not get the error:
[2023-04-09 07:56:05.974 -04:00] [Error] [PluginAPI] Failed loading plugin Test Plugin,
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException (System.ExceptionResource resource) [0x0000b] in <9577ac7a62ef43179789031239ba8798>:0
at System.Collections.Generic.List`1+Enumerator[T].MoveNextRare () [0x00013] in <9577ac7a62ef43179789031239ba8798>:0
at System.Collections.Generic.List`1+Enumerator[T].MoveNext () [0x0004a] in <9577ac7a62ef43179789031239ba8798>:0
at System.Linq.Enumerable+SelectListIterator`2[TSource,TResult].MoveNext () [0x00029] in <351e49e2a5bf4fd6beabb458ce2255f3>:0
at System.Linq.Enumerable+SelectManySingleSelectorIterator`2[TSource,TResult].MoveNext () [0x0006f] in <351e49e2a5bf4fd6beabb458ce2255f3>:0
at System.Linq.Enumerable+DistinctIterator`1[TSource].MoveNext () [0x0009a] in <351e49e2a5bf4fd6beabb458ce2255f3>:0
at PluginAPI.Events.EventManager.UnregisterAllEvents (System.Object plugin) [0x0007f] in <8eb2b959a7ee45a88abe21e98f866aab>:0
I only got the error sometimes.
I managed to fix this like so:
Change
public static void UnregisterAllEvents(object plugin)
{
Type pluginType = plugin.GetType();
foreach (var handler in Events
.SelectMany(x =>
x.Value.Invokers.Where(y => y.Key == pluginType))
.SelectMany(x =>
x.Value.Select(y => y.Target))
.Distinct())
{
UnregisterEvents(pluginType, handler);
}
}
to
public void UnregisterAllEvents(object plugin)
{
Type pluginType = plugin.GetType();
var handlers = EventManager.Events
.SelectMany(x =>
x.Value.Invokers.Where(y => y.Key == pluginType))
.SelectMany(x =>
x.Value.Select(y => y.Target))
.Distinct().ToList();
for (int i = 0; i < handlers.Count; i++)
{
UnregisterEvents(pluginType, handlers[i]);
}
}