我正在尝试使用在我定义的委托之外定义的引用(我正在处理的简化版本):
private void DoStuff(int objectKey)
{
MyObject myObject;
if (this.concurrentDictionary.TryRemove(objectKey, out myObject))
{
Action<IList<IEvent>> eventsCompletedDelegate (eventList) =>
{
// Do work ...
myObject.DoSomething();
};
ExecuteStuffAsync(eventsCompletedDelegate);
}
}
问题是eventsCompletedDelegate是异步执行的(在调用ExecuteStuffAsync之后的某个时间)。我希望能够从闭包中访问myObject,但是在调用委托时,将释放本地myObject引用。有没有办法将myObject传递给委托,以便在调用委托时它仍然可用?
答案 0 :(得分:-1)
不,myObject不会被处置,因为来自eventsCompletedDelegate(variable capture)的引用。这是内存泄漏的常见原因。
答案 1 :(得分:-1)
如果您创建myObject的对象引用x
并将其传递给您的操作,则您的“复制”引用x
仍将在回调中可用,并且不会被垃圾回收。 / p>
这将输出“达到DoSomething 1”。
但是,如果处理引用,如Enigmativity所述,这也将修改复制的引用,调用dispos。这将改为输出“达到DoSomething 0”。除了确保在调用回调之前不调配myObject之外,没有办法阻止这种情况。
void Main()
{
concurrentDictionary[1] = new MyObject(1);
DoStuff(1);
}
private ConcurrentDictionary<int, MyObject> concurrentDictionary =
new ConcurrentDictionary<int, UserQuery.MyObject>();
private async void DoStuff(int objectKey)
{
MyObject myObject;
if (this.concurrentDictionary.TryRemove(objectKey, out myObject))
{
Action<MyObject> eventsCompletedDelegate = (objectRef) =>
{
objectRef.DoSomething();
};
var x = myObject;
// myObject.Dispose(); // will set _id to 0 if called
myObject = null;
await ExecuteStuffAsync(() => eventsCompletedDelegate(x));
}
}
public async Task ExecuteStuffAsync(Action callback)
{
await Task.Delay(1000);
callback();
}
public class MyObject : IDisposable
{
private int _id;
public MyObject(int id)
{
_id = id;
}
public void Dispose() { _id = 0; }
public void DoSomething()
{
Console.WriteLine("reached DoSomething " + _id);
}
}