1)我听说当我们不调用EndInvoke()时可能会导致内存泄漏?你能证明这会导致内存泄漏吗?
2)当我想调用EndInvoke()时,我会使用如下代码吗?
namespace BlockMechanism
{
public delegate int MyDelegate(List<int> someInts);
class MainClass
{
static void Main()
{
List<int> someInts = new List<int> { 1, 2, 3, 4, 5, 6, 7 };
MyDelegate test = FinalResult;
IAsyncResult res=test.BeginInvoke(someInts, null, test);
Console.WriteLine(test.EndInvoke(res));
Console.ReadKey(true);
}
public static int FinalResult(List<int> Mylist)
{
return Mylist.Sum();
}
}
}
答案 0 :(得分:4)
虽然您的示例是正确的,但是使用不同的线程没有任何好处,因为您在主线程上调用EndInvoke
将阻塞直到操作完成且无法执行其他工作。如果您在委托上调用Invoke
或直接调用FinalResult
方法本身,则会相同。通常在EndInvoke
方法提供的回调中调用BeginInvoke
:
class Program
{
public delegate int MyDelegate(List<int> someInts);
class MainClass
{
static void Main()
{
List<int> someInts = new List<int> { 1, 2, 3, 4, 5, 6, 7 };
MyDelegate test = FinalResult;
test.BeginInvoke(someInts, ar =>
{
MyDelegate del = (MyDelegate)ar.AsyncState;
Console.WriteLine(del.EndInvoke(ar));
}, test);
Console.ReadKey(true);
}
public static int FinalResult(List<int> Mylist)
{
return Mylist.Sum();
}
}
}
就内存泄漏而言,您可以查看此thread。
P.S:List<T>类的实例成员不是线程安全的,因此当您从多个线程访问它们时应该小心。
答案 1 :(得分:2)
MSDN article on Begin/EndInvoke()
基本上,如果你不打电话给EndInvoke()
,你就有可能泄漏
本文讨论了使用BeginInvoke()
的四种常用方法,以及何时应为每个方法调用EndInvoke()
。
对于后代,我会在这里复制它们:
做一些工作,然后调用EndInvoke来阻止,直到调用完成。
使用System.IAsyncResult.AsyncWaitHandle属性获取WaitHandle,使用其WaitOne方法阻止执行,直到发出WaitHandle信号,然后调用EndInvoke。
轮询BeginInvoke返回的IAsyncResult以确定异步调用何时完成,然后调用EndInvoke。
将一个回调方法的委托传递给BeginInvoke。异步调用完成时,该方法在ThreadPool线程上执行。回调方法调用EndInvoke。