Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2e040ea

Browse files
authored
Merge pull request #2 from losttech/ManagedType-DontKeepBorrowedRefs
Reworked `ManagedType` to not keep python references to self
2 parents 44d65d9 + a86994f commit 2e040ea

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+1802
-1819
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ One must now either use enum members (e.g. `MyEnum.Option`), or use enum constru
6565
- BREAKING: Names of .NET types (e.g. `str(__class__)`) changed to better support generic types
6666
- BREAKING: overload resolution will no longer prefer basic types. Instead, first matching overload will
6767
be chosen.
68+
- BREAKING: `Exec` and `Eval` from `PythonEngine` no longer accept raw pointers.
6869
- BREAKING: .NET collections and arrays are no longer automatically converted to
6970
Python collections. Instead, they implement standard Python
7071
collection interfaces from `collections.abc`.
@@ -74,6 +75,7 @@ be of type `PyInt` instead of `System.Int32` due to possible loss of information
7475
Python `float` will continue to be converted to `System.Double`.
7576
- BREAKING: Python.NET will no longer implicitly convert types like `numpy.float64`, that implement `__float__` to
7677
`System.Single` and `System.Double`. An explicit conversion is required on Python or .NET side.
78+
- BREAKING: `PyObject.GetHashCode` can fail.
7779
- BREAKING: Python.NET will no longer implicitly convert any Python object to `System.Boolean`.
7880
- BREAKING: `PyObject.GetAttr(name, default)` now only ignores `AttributeError` (previously ignored all exceptions).
7981
- BREAKING: `PyObject` no longer implements `IEnumerable<PyObject>`.

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<PrivateAssets>all</PrivateAssets>
1414
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
1515
</PackageReference>
16-
<PackageReference Include="Lost.NonCopyableAnalyzer" Version="0.7.0-m04">
16+
<PackageReference Include="Lost.NonCopyableAnalyzer" Version="0.7.0-m05">
1717
<PrivateAssets>all</PrivateAssets>
1818
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1919
</PackageReference>

pythonnet.sln

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ Global
5454
Release|Any CPU = Release|Any CPU
5555
Release|x64 = Release|x64
5656
Release|x86 = Release|x86
57+
TraceAlloc|Any CPU = TraceAlloc|Any CPU
58+
TraceAlloc|x64 = TraceAlloc|x64
59+
TraceAlloc|x86 = TraceAlloc|x86
5760
EndGlobalSection
5861
GlobalSection(ProjectConfigurationPlatforms) = postSolution
5962
{4E8C8FE2-0FB8-4517-B2D9-5FB2D5FC849B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -68,6 +71,12 @@ Global
6871
{4E8C8FE2-0FB8-4517-B2D9-5FB2D5FC849B}.Release|x64.Build.0 = Release|Any CPU
6972
{4E8C8FE2-0FB8-4517-B2D9-5FB2D5FC849B}.Release|x86.ActiveCfg = Release|Any CPU
7073
{4E8C8FE2-0FB8-4517-B2D9-5FB2D5FC849B}.Release|x86.Build.0 = Release|Any CPU
74+
{4E8C8FE2-0FB8-4517-B2D9-5FB2D5FC849B}.TraceAlloc|Any CPU.ActiveCfg = TraceAlloc|Any CPU
75+
{4E8C8FE2-0FB8-4517-B2D9-5FB2D5FC849B}.TraceAlloc|Any CPU.Build.0 = TraceAlloc|Any CPU
76+
{4E8C8FE2-0FB8-4517-B2D9-5FB2D5FC849B}.TraceAlloc|x64.ActiveCfg = Debug|Any CPU
77+
{4E8C8FE2-0FB8-4517-B2D9-5FB2D5FC849B}.TraceAlloc|x64.Build.0 = Debug|Any CPU
78+
{4E8C8FE2-0FB8-4517-B2D9-5FB2D5FC849B}.TraceAlloc|x86.ActiveCfg = Debug|Any CPU
79+
{4E8C8FE2-0FB8-4517-B2D9-5FB2D5FC849B}.TraceAlloc|x86.Build.0 = Debug|Any CPU
7180
{E6B01706-00BA-4144-9029-186AC42FBE9A}.Debug|Any CPU.ActiveCfg = Debug|x64
7281
{E6B01706-00BA-4144-9029-186AC42FBE9A}.Debug|Any CPU.Build.0 = Debug|x64
7382
{E6B01706-00BA-4144-9029-186AC42FBE9A}.Debug|x64.ActiveCfg = Debug|x64
@@ -80,6 +89,12 @@ Global
8089
{E6B01706-00BA-4144-9029-186AC42FBE9A}.Release|x64.Build.0 = Release|x64
8190
{E6B01706-00BA-4144-9029-186AC42FBE9A}.Release|x86.ActiveCfg = Release|x86
8291
{E6B01706-00BA-4144-9029-186AC42FBE9A}.Release|x86.Build.0 = Release|x86
92+
{E6B01706-00BA-4144-9029-186AC42FBE9A}.TraceAlloc|Any CPU.ActiveCfg = Debug|x64
93+
{E6B01706-00BA-4144-9029-186AC42FBE9A}.TraceAlloc|Any CPU.Build.0 = Debug|x64
94+
{E6B01706-00BA-4144-9029-186AC42FBE9A}.TraceAlloc|x64.ActiveCfg = Debug|x64
95+
{E6B01706-00BA-4144-9029-186AC42FBE9A}.TraceAlloc|x64.Build.0 = Debug|x64
96+
{E6B01706-00BA-4144-9029-186AC42FBE9A}.TraceAlloc|x86.ActiveCfg = Debug|x86
97+
{E6B01706-00BA-4144-9029-186AC42FBE9A}.TraceAlloc|x86.Build.0 = Debug|x86
8398
{819E089B-4770-400E-93C6-4F7A35F0EA12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
8499
{819E089B-4770-400E-93C6-4F7A35F0EA12}.Debug|Any CPU.Build.0 = Debug|Any CPU
85100
{819E089B-4770-400E-93C6-4F7A35F0EA12}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -92,6 +107,12 @@ Global
92107
{819E089B-4770-400E-93C6-4F7A35F0EA12}.Release|x64.Build.0 = Release|Any CPU
93108
{819E089B-4770-400E-93C6-4F7A35F0EA12}.Release|x86.ActiveCfg = Release|Any CPU
94109
{819E089B-4770-400E-93C6-4F7A35F0EA12}.Release|x86.Build.0 = Release|Any CPU
110+
{819E089B-4770-400E-93C6-4F7A35F0EA12}.TraceAlloc|Any CPU.ActiveCfg = Debug|Any CPU
111+
{819E089B-4770-400E-93C6-4F7A35F0EA12}.TraceAlloc|Any CPU.Build.0 = Debug|Any CPU
112+
{819E089B-4770-400E-93C6-4F7A35F0EA12}.TraceAlloc|x64.ActiveCfg = Debug|Any CPU
113+
{819E089B-4770-400E-93C6-4F7A35F0EA12}.TraceAlloc|x64.Build.0 = Debug|Any CPU
114+
{819E089B-4770-400E-93C6-4F7A35F0EA12}.TraceAlloc|x86.ActiveCfg = Debug|Any CPU
115+
{819E089B-4770-400E-93C6-4F7A35F0EA12}.TraceAlloc|x86.Build.0 = Debug|Any CPU
95116
{14EF9518-5BB7-4F83-8686-015BD2CC788E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
96117
{14EF9518-5BB7-4F83-8686-015BD2CC788E}.Debug|Any CPU.Build.0 = Debug|Any CPU
97118
{14EF9518-5BB7-4F83-8686-015BD2CC788E}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -104,6 +125,12 @@ Global
104125
{14EF9518-5BB7-4F83-8686-015BD2CC788E}.Release|x64.Build.0 = Release|Any CPU
105126
{14EF9518-5BB7-4F83-8686-015BD2CC788E}.Release|x86.ActiveCfg = Release|Any CPU
106127
{14EF9518-5BB7-4F83-8686-015BD2CC788E}.Release|x86.Build.0 = Release|Any CPU
128+
{14EF9518-5BB7-4F83-8686-015BD2CC788E}.TraceAlloc|Any CPU.ActiveCfg = Debug|Any CPU
129+
{14EF9518-5BB7-4F83-8686-015BD2CC788E}.TraceAlloc|Any CPU.Build.0 = Debug|Any CPU
130+
{14EF9518-5BB7-4F83-8686-015BD2CC788E}.TraceAlloc|x64.ActiveCfg = Debug|Any CPU
131+
{14EF9518-5BB7-4F83-8686-015BD2CC788E}.TraceAlloc|x64.Build.0 = Debug|Any CPU
132+
{14EF9518-5BB7-4F83-8686-015BD2CC788E}.TraceAlloc|x86.ActiveCfg = Debug|Any CPU
133+
{14EF9518-5BB7-4F83-8686-015BD2CC788E}.TraceAlloc|x86.Build.0 = Debug|Any CPU
107134
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.Debug|Any CPU.ActiveCfg = Debug|x64
108135
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.Debug|Any CPU.Build.0 = Debug|x64
109136
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.Debug|x64.ActiveCfg = Debug|x64
@@ -116,6 +143,12 @@ Global
116143
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.Release|x64.Build.0 = Release|x64
117144
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.Release|x86.ActiveCfg = Release|x86
118145
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.Release|x86.Build.0 = Release|x86
146+
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.TraceAlloc|Any CPU.ActiveCfg = Debug|x64
147+
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.TraceAlloc|Any CPU.Build.0 = Debug|x64
148+
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.TraceAlloc|x64.ActiveCfg = Debug|x64
149+
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.TraceAlloc|x64.Build.0 = Debug|x64
150+
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.TraceAlloc|x86.ActiveCfg = Debug|x86
151+
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.TraceAlloc|x86.Build.0 = Debug|x86
119152
{F2FB6DA3-318E-4F30-9A1F-932C667E38C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
120153
{F2FB6DA3-318E-4F30-9A1F-932C667E38C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
121154
{F2FB6DA3-318E-4F30-9A1F-932C667E38C5}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -128,6 +161,12 @@ Global
128161
{F2FB6DA3-318E-4F30-9A1F-932C667E38C5}.Release|x64.Build.0 = Release|Any CPU
129162
{F2FB6DA3-318E-4F30-9A1F-932C667E38C5}.Release|x86.ActiveCfg = Release|Any CPU
130163
{F2FB6DA3-318E-4F30-9A1F-932C667E38C5}.Release|x86.Build.0 = Release|Any CPU
164+
{F2FB6DA3-318E-4F30-9A1F-932C667E38C5}.TraceAlloc|Any CPU.ActiveCfg = Debug|Any CPU
165+
{F2FB6DA3-318E-4F30-9A1F-932C667E38C5}.TraceAlloc|Any CPU.Build.0 = Debug|Any CPU
166+
{F2FB6DA3-318E-4F30-9A1F-932C667E38C5}.TraceAlloc|x64.ActiveCfg = Debug|Any CPU
167+
{F2FB6DA3-318E-4F30-9A1F-932C667E38C5}.TraceAlloc|x64.Build.0 = Debug|Any CPU
168+
{F2FB6DA3-318E-4F30-9A1F-932C667E38C5}.TraceAlloc|x86.ActiveCfg = Debug|Any CPU
169+
{F2FB6DA3-318E-4F30-9A1F-932C667E38C5}.TraceAlloc|x86.Build.0 = Debug|Any CPU
131170
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
132171
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Debug|Any CPU.Build.0 = Debug|Any CPU
133172
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -140,6 +179,12 @@ Global
140179
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Release|x64.Build.0 = Release|Any CPU
141180
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Release|x86.ActiveCfg = Release|Any CPU
142181
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Release|x86.Build.0 = Release|Any CPU
182+
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.TraceAlloc|Any CPU.ActiveCfg = Debug|Any CPU
183+
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.TraceAlloc|Any CPU.Build.0 = Debug|Any CPU
184+
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.TraceAlloc|x64.ActiveCfg = Debug|Any CPU
185+
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.TraceAlloc|x64.Build.0 = Debug|Any CPU
186+
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.TraceAlloc|x86.ActiveCfg = Debug|Any CPU
187+
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.TraceAlloc|x86.Build.0 = Debug|Any CPU
143188
EndGlobalSection
144189
GlobalSection(SolutionProperties) = preSolution
145190
HideSolutionNode = FALSE

src/embed_tests/CallableObject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public void SetUp()
1414
{
1515
PythonEngine.Initialize();
1616
using var locals = new PyDict();
17-
PythonEngine.Exec(CallViaInheritance.BaseClassSource, locals: locals.Handle);
17+
PythonEngine.Exec(CallViaInheritance.BaseClassSource, locals: locals);
1818
CustomBaseTypeProvider.BaseClass = new PyType(locals[CallViaInheritance.BaseClassName]);
1919
PythonEngine.InteropConfiguration.PythonBaseTypeProviders.Add(new CustomBaseTypeProvider());
2020
}

src/embed_tests/Inheritance.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ public class Inheritance
1313
public void SetUp()
1414
{
1515
PythonEngine.Initialize();
16-
var locals = new PyDict();
17-
PythonEngine.Exec(InheritanceTestBaseClassWrapper.ClassSourceCode, locals: locals.Handle);
16+
using var locals = new PyDict();
17+
PythonEngine.Exec(InheritanceTestBaseClassWrapper.ClassSourceCode, locals: locals);
1818
ExtraBaseTypeProvider.ExtraBase = new PyType(locals[InheritanceTestBaseClassWrapper.ClassName]);
1919
var baseTypeProviders = PythonEngine.InteropConfiguration.PythonBaseTypeProviders;
2020
baseTypeProviders.Add(new ExtraBaseTypeProvider());

src/embed_tests/TestNamedArguments.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def Test3(self, a1 = 1, a2 = 1, a3 = 1, a4 = 1):
5555
return a1 + a2 + a3 + a4
5656
5757
a = cmTest3()
58-
", null, locals.Handle);
58+
", null, locals);
5959

6060
return locals.GetItem("a");
6161
}

src/embed_tests/TestPyObject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def add(self, x, y):
4646
return x + y
4747
4848
a = MemberNamesTest()
49-
", null, locals.Handle);
49+
", null, locals);
5050

5151
PyObject a = locals.GetItem("a");
5252

src/embed_tests/TestPyWith.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def fail(self):
3737
return 5 / 0
3838
3939
a = CmTest()
40-
", null, locals.Handle);
40+
", null, locals);
4141

4242
var a = locals.GetItem("a");
4343

@@ -76,7 +76,7 @@ def fail(self):
7676
return 5 / 0
7777
7878
a = CmTest()
79-
", null, locals.Handle);
79+
", null, locals);
8080

8181
var a = locals.GetItem("a");
8282
Py.With(a, cmTest =>

src/embed_tests/TestRuntime.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,12 @@ public static void RefCountTest()
5555
Assert.AreEqual(1, Runtime.Runtime.Refcount32(p));
5656

5757
// XIncref/XDecref increase and decrease RefCount
58+
#pragma warning disable CS0618 // Type or member is obsolete. We are testing corresponding members
5859
Runtime.Runtime.XIncref(p);
5960
Assert.AreEqual(2, Runtime.Runtime.Refcount32(p));
60-
Runtime.Runtime.XDecref(p);
61+
Runtime.Runtime.XDecref(op.Steal());
6162
Assert.AreEqual(1, Runtime.Runtime.Refcount32(p));
63+
#pragma warning restore CS0618 // Type or member is obsolete
6264

6365
op.Dispose();
6466

src/embed_tests/pyrunstring.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void TestEval()
3737
locals.SetItem("sys", sys);
3838
locals.SetItem("a", new PyInt(10));
3939

40-
object b = PythonEngine.Eval("sys.attr1 + a + 1", null, locals.Handle)
40+
object b = PythonEngine.Eval("sys.attr1 + a + 1", null, locals)
4141
.AsManagedObject(typeof(int));
4242
Assert.AreEqual(111, b);
4343
}
@@ -51,7 +51,7 @@ public void TestExec()
5151
locals.SetItem("sys", sys);
5252
locals.SetItem("a", new PyInt(10));
5353

54-
PythonEngine.Exec("c = sys.attr1 + a + 1", null, locals.Handle);
54+
PythonEngine.Exec("c = sys.attr1 + a + 1", null, locals);
5555
object c = locals.GetItem("c").AsManagedObject(typeof(int));
5656
Assert.AreEqual(111, c);
5757
}

src/runtime/BorrowedReference.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
namespace Python.Runtime
22
{
33
using System;
4+
using System.Diagnostics;
5+
46
/// <summary>
57
/// Represents a reference to a Python object, that is being lent, and
68
/// can only be safely used until execution returns to the caller.
@@ -11,6 +13,7 @@ readonly ref struct BorrowedReference
1113
public bool IsNull => this.pointer == IntPtr.Zero;
1214

1315
/// <summary>Gets a raw pointer to the Python object</summary>
16+
[DebuggerHidden]
1417
public IntPtr DangerousGetAddress()
1518
=> this.IsNull ? throw new NullReferenceException() : this.pointer;
1619
/// <summary>Gets a raw pointer to the Python object</summary>

src/runtime/DefaultBaseTypeProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ static BorrowedReference GetBaseType(Type type)
2424
return Exceptions.Exception;
2525

2626
return type.BaseType is not null
27-
? ClassManager.GetClass(type.BaseType).ObjectReference
27+
? ClassManager.GetClass(type.BaseType)
2828
: Runtime.PyBaseObjectType;
2929
}
3030

src/runtime/EventHandlerCollection.cs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection;
4+
using System.Runtime.Serialization;
5+
using System.Security.Permissions;
6+
7+
namespace Python.Runtime;
8+
9+
[Serializable]
10+
internal class EventHandlerCollection: Dictionary<object, List<Handler>>
11+
{
12+
readonly EventInfo info;
13+
public EventHandlerCollection(EventInfo @event)
14+
{
15+
info = @event;
16+
}
17+
18+
/// <summary>
19+
/// Register a new Python object event handler with the event.
20+
/// </summary>
21+
internal bool AddEventHandler(BorrowedReference target, PyObject handler)
22+
{
23+
object? obj = null;
24+
if (target != null)
25+
{
26+
var co = (CLRObject)ManagedType.GetManagedObject(target)!;
27+
obj = co.inst;
28+
}
29+
30+
// Create a true delegate instance of the appropriate type to
31+
// wrap the Python handler. Note that wrapper delegate creation
32+
// always succeeds, though calling the wrapper may fail.
33+
Type type = info.EventHandlerType;
34+
Delegate d = PythonEngine.DelegateManager.GetDelegate(type, handler);
35+
36+
// Now register the handler in a mapping from instance to pairs
37+
// of (handler hash, delegate) so we can lookup to remove later.
38+
object key = obj ?? info.ReflectedType;
39+
if (!TryGetValue(key, out var list))
40+
{
41+
list = new List<Handler>();
42+
this[key] = list;
43+
}
44+
list.Add(new Handler(Runtime.PyObject_Hash(handler), d));
45+
46+
// Note that AddEventHandler helper only works for public events,
47+
// so we have to get the underlying add method explicitly.
48+
object[] args = { d };
49+
MethodInfo mi = info.GetAddMethod(true);
50+
mi.Invoke(obj, BindingFlags.Default, null, args, null);
51+
52+
return true;
53+
}
54+
55+
56+
/// <summary>
57+
/// Remove the given Python object event handler.
58+
/// </summary>
59+
internal bool RemoveEventHandler(BorrowedReference target, BorrowedReference handler)
60+
{
61+
object? obj = null;
62+
if (target != null)
63+
{
64+
var co = (CLRObject)ManagedType.GetManagedObject(target)!;
65+
obj = co.inst;
66+
}
67+
68+
nint hash = Runtime.PyObject_Hash(handler);
69+
if (hash == -1 && Exceptions.ErrorOccurred())
70+
{
71+
return false;
72+
}
73+
74+
object key = obj ?? info.ReflectedType;
75+
76+
if (!TryGetValue(key, out var list))
77+
{
78+
Exceptions.SetError(Exceptions.ValueError, "unknown event handler");
79+
return false;
80+
}
81+
82+
object?[] args = { null };
83+
MethodInfo mi = info.GetRemoveMethod(true);
84+
85+
for (var i = 0; i < list.Count; i++)
86+
{
87+
var item = (Handler)list[i];
88+
if (item.hash != hash)
89+
{
90+
continue;
91+
}
92+
args[0] = item.del;
93+
try
94+
{
95+
mi.Invoke(obj, BindingFlags.Default, null, args, null);
96+
}
97+
catch
98+
{
99+
continue;
100+
}
101+
list.RemoveAt(i);
102+
return true;
103+
}
104+
105+
Exceptions.SetError(Exceptions.ValueError, "unknown event handler");
106+
return false;
107+
}
108+
109+
#region Serializable
110+
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
111+
protected EventHandlerCollection(SerializationInfo info, StreamingContext context)
112+
: base(info, context)
113+
{
114+
this.info = (EventInfo)info.GetValue("event", typeof(EventInfo));
115+
}
116+
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
117+
public override void GetObjectData(SerializationInfo info, StreamingContext context)
118+
{
119+
base.GetObjectData(info, context);
120+
121+
info.AddValue("event", this.info);
122+
}
123+
#endregion
124+
}

0 commit comments

Comments
 (0)