Die Verwendung einer Methodengruppenumsetzung anstelle eines Delegaten ist in Ordnung, die EndInvoke
wird immer noch auf Ihrem Action
aufgerufen werden. Es gibt nichts anderes zu tun, da dies ein Feuer- und Vergessensruf ist.
Leider ist es schwer, direkt zu beweisen, dass EndInvoke aufgerufen wird, da Action
ein Delegat ist und wir nicht einfach einen Haltepunkt für eine Klasse in der BCL hinzufügen können.
Dieser Code wird (periodisch) einigen privaten Bereich des IAsyncResult inspiziert, die von BeginInvoke
zurückgeführt wird, die Spur davon, ob zu halten scheint oder nicht EndInvoke
noch genannt worden ist:
public partial class MainWindow : Window
{
private Timer _timer = new Timer(TimerCallback, null, 100, 100);
private static IAsyncResult _asyncResult;
public MainWindow()
{
InitializeComponent();
}
static void LongRunTime()
{
Thread.Sleep(1000);
}
void Window_Loaded(object sender, RoutedEventArgs args)
{
Action myAction =() => LongRunTime();
_asyncResult = myAction.BeginInvoke(myAction.EndInvoke, null);
}
static void TimerCallback(object obj)
{
if (_asyncResult != null)
{
bool called = ((dynamic)_asyncResult).EndInvokeCalled;
if (called)
{
// Will hit this breakpoint after LongRuntime has completed
Debugger.Break();
_asyncResult = null;
}
}
}
}
ich doppelt habe geprüft unter Verwendung SOS, dass es keine verwalteten Speicherlecks gibt. Ich habe auch einige andere Beweise versucht, aber sie waren umständlicher als diese, denke ich.
Einige interessante ich während meiner Untersuchung entdeckt: die myAction.BeginInvoke
Aufruf wird auf Profiler mit Instrumentierung angezeigt, aber myAction.EndInvoke
nicht.
Ich sehe kein Problem mit der Verwendung einer Methodengruppe Konvertierung über einen Lambda-Ausdruck. – Thorarin
Wenn Sie eine Antwort auf die eine oder andere Weise hinzufügen können, wenn diese Technik keinen Speicherverlust verursacht, dann wäre das die Antwort, nach der ich suche. Vielen Dank! –