InvokeAsync와 BeginInvoke for WPF Dispatcher의 차이점은 무엇입니까?
.NET 4.5에서 WPF Dispatcher 가 InvokeAsync 라는 Dispatcher의 스레드에서 항목을 실행하는 새로운 메서드 집합을 얻었 습니다 . 이전에는 .NET 4.5에서 Invoke 와 BeginInvoke를 사용하여 이를 각각 동기식 및 비동기식으로 처리했습니다.
사용 가능한 이름 지정 및 약간 다른 오버로드 외에 BeginInvoke
와 InvokeAsync
메서드 간에 큰 차이점이 있습니까?
아, 그리고 이미 확인했습니다. 둘 다 await
편집 할 수 있습니다 .
private async Task RunStuffOnUiThread(Action action)
{
// both of these works fine
await dispatcher.BeginInvoke(action);
await dispatcher.InvokeAsync(action);
}
BeginInvoke
메서드가 LegacyBeginInvokeImpl
private 메서드 InvokeAsyncImpl
(에서 사용 하는 메서드)를 호출하는 private 메서드를 호출하므로 차이가 없습니다 InvokeAsync
. 그래서 그것은 기본적으로 같은 것입니다. 단순한 리팩토링 인 것 같지만 BeginInvoke
메소드가 쓸모없는 것으로 표시되지 않은 것이 이상합니다.
BeginInvoke :
public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method)
{
return this.LegacyBeginInvokeImpl(priority, method, null, 0);
}
private DispatcherOperation LegacyBeginInvokeImpl(DispatcherPriority priority, Delegate method, object args, int numArgs)
{
Dispatcher.ValidatePriority(priority, "priority");
if (method == null)
{
throw new ArgumentNullException("method");
}
DispatcherOperation dispatcherOperation = new DispatcherOperation(this, method, priority, args, numArgs);
this.InvokeAsyncImpl(dispatcherOperation, CancellationToken.None);
return dispatcherOperation;
}
InvokeAsync :
public DispatcherOperation InvokeAsync(Action callback, DispatcherPriority priority)
{
return this.InvokeAsync(callback, priority, CancellationToken.None);
}
public DispatcherOperation InvokeAsync(Action callback, DispatcherPriority priority, CancellationToken cancellationToken)
{
if (callback == null)
{
throw new ArgumentNullException("callback");
}
Dispatcher.ValidatePriority(priority, "priority");
DispatcherOperation dispatcherOperation = new DispatcherOperation(this, priority, callback);
this.InvokeAsyncImpl(dispatcherOperation, cancellationToken);
return dispatcherOperation;
}
예외 처리가 다릅니다.
다음 사항을 확인할 수 있습니다.
private async void OnClick(object sender, RoutedEventArgs e)
{
Dispatcher.UnhandledException += OnUnhandledException;
try
{
await Dispatcher.BeginInvoke((Action)(Throw));
}
catch
{
// The exception is not handled here but in the unhandled exception handler.
MessageBox.Show("Catched BeginInvoke.");
}
try
{
await Dispatcher.InvokeAsync((Action)Throw);
}
catch
{
MessageBox.Show("Catched InvokeAsync.");
}
}
private void OnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show("Catched UnhandledException");
}
private void Throw()
{
throw new Exception();
}
메서드 서명에는 차이가 있습니다.
BeginInvoke(Delegate, Object[])
InvokeAsync(Action)
들어 BeginInvoke()
컴파일러 배열을 생성 Object[]
하기위한 동안 암시 InvokeAsync()
같은 배열이 필요하지 않습니다 :
IL_0001: ldarg.0
IL_0002: call instance class [WindowsBase]System.Windows.Threading.Dispatcher [WindowsBase]System.Windows.Threading.DispatcherObject::get_Dispatcher()
IL_0007: ldarg.1
IL_0008: ldc.i4.0
IL_0009: newarr [mscorlib]System.Object
IL_000e: callvirt instance class [WindowsBase]System.Windows.Threading.DispatcherOperation [WindowsBase]System.Windows.Threading.Dispatcher::BeginInvoke(class [mscorlib]System.Delegate, object[])
IL_0014: ldarg.0
IL_0015: call instance class [WindowsBase]System.Windows.Threading.Dispatcher [WindowsBase]System.Windows.Threading.DispatcherObject::get_Dispatcher()
IL_001a: ldarg.1
IL_001b: callvirt instance class [WindowsBase]System.Windows.Threading.DispatcherOperation [WindowsBase]System.Windows.Threading.Dispatcher::InvokeAsync(class [mscorlib]System.Action)
Well, one difference I've noticed is that InvokeAsync has a generic overload that returns a DispatcherOperation as a return value and accepts a Func as its delegate input parameter. Thus, you can retrieve the result of the operation via InvokeAsync in a type-safe way analogous to how you can await the result of a Task.
'developer tip' 카테고리의 다른 글
"final int i"는 Java for 루프 내에서 어떻게 작동합니까? (0) | 2020.12.05 |
---|---|
PHP에서 REST API를 빌드하려면 프레임 워크가 필요합니까? (0) | 2020.12.05 |
ELF 파일 형식에서 섹션과 세그먼트의 차이점은 무엇입니까 (0) | 2020.12.05 |
Rails 3 인증 솔루션 (0) | 2020.12.05 |
TypeScript에서 전역 변수 만들기 (0) | 2020.12.05 |