Обычно, VM сделал бы сборку "мусора" автоматически прежде, чем бросить OutOfMemoryException, так добавление, что явный вызов не должен помогать, кроме которого это, возможно, перемещает хит производительности в более ранний момент вовремя.
Однако я думаю, что встретился со случаем, где это могло бы быть релевантно. Я не уверен, хотя, поскольку я должен все же протестировать, имеет ли это какой-либо эффект:
, Когда Вы карта распределения памяти файл, я верю карте () вызов бросает IOException, когда достаточно большой блок памяти не доступен. Сборка "мусора" незадолго до карты () файл мог бы помочь предотвратить это, я думаю. Что Вы думаете?
Причина, по которой вам нужно вызвать EndInvoke
, - это избежать утечки памяти; .Net будет хранить информацию о результате (или исключении) функции до тех пор, пока вы не вызовете EndInvoke
.
Вы можете вызвать EndInvoke
в обработчике завершения, который вы передаете BeginInvoke
и сохранить асинхронный характер.
РЕДАКТИРОВАТЬ :
Например:
class Program {
private delegate void GenerateXmlDelegate();
static void Main(string[] args) {
GenerateXmlDelegate worker = new GenerateXmlDelegate(GenerateMainXml);
IAsyncResult result = worker.BeginInvoke(delegate {
try {
worker.EndInvoke();
} catch(...) { ... }
}, null);
}
private static void GenerateMainXml() {
Thread.Sleep(10000);
Console.WriteLine("GenerateMainXml Called by delegate");
}
}
Если вы хотите запустить асинхронный вызов и забыть о нем, вы можете использовать ThreadPool , например:
ThreadPool.QueueUserWorkItem(delegate { GenerateMainXml(); });
Как сказал SLaks, EndInvoke
обеспечивает защиту от утечек памяти.
BeginInvoke
по-прежнему асинхронный; рассмотрите следующий код:
static void Main() {
Func<double> slowCalculator = new Func<double>(PerformSlowCalculation);
IAsyncResult slowCalculation = slowCalculator.BeginInvoke(null, null);
// lots of stuff to do while slowCalculator is doing its thing
Console.WriteLine("Result is {0}", slowCalculator.EndInvoke(slowCalculation));
}
static double PerformSlowCalculation() {
double result;
// lots and lots of code
return result;
}
Если бы этот код был написан без вызовов BeginInvoke
/ EndInvoke
, PerformSlowCalculation
должен был бы завершиться до Main
мог бы делать остальную часть своего «множества вещей»; таким образом, оба события могут происходить одновременно.
Теперь, в вашем примере с использованием GenerateXmlDelegate
, вам по-прежнему требуется EndInvoke
, даже если вы ничего не возвращаете. Это можно сделать следующим образом:
static void Main(string[] args) {
GenerateXmlDelegate worker = new GenerateXmlDelegate(GenerateMainXml);
IAsyncResult result = worker.BeginInvoke(GenerateXmlComplete, null);
}
private static void GenerateXmlComplete(IAsyncResult result) {
AsyncResult realResult = result as AsyncResult;
GenerateXmlDelegate worker = result.AsyncDelegate as GenerateXmlDelegate;
worker.EndInvoke();
}