BeginInvoke에 전달한 람다 함수에 CS1660 에러가 발생하는 경우
WPF 프로젝트를 만들고, 다음과 같이 BeginInvoke를 호출하려고 했습니다.
using System.Windows;
namespace WpfApp1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// 컴파일 오류 발생: CS1660
this.Dispatcher.BeginInvoke((arg) =>
{
}, null);
}
}
}
그런데, 다음과 같은 컴파일 오류가 발생합니다.
error CS1660: Cannot convert lambda expression to type 'DispatcherPriority' because it is not a delegate type
// 또는
error CS1660: Cannot convert lambda expression to type 'Delegate' because it is not a delegate type
정말 이상하군요... 예전에 잘 사용한 적이 있었던 것 같은데?!!!
이런 경우, 다음과 같이 바꿔주면 컴파일이 잘 됩니다.
// 전달해야 할 인자가 있는 경우,
this.Dispatcher.BeginInvoke((System.Action<object>)((arg) =>
{
MessageBox.Show("TEST");
}), this);
// 전달해야 할 인자가 없는 경우,
this.Dispatcher.BeginInvoke((System.Action)(() =>
{
MessageBox.Show("TEST");
}), null);
그래도 왠지... 명시적인 형 변환이 마음에 들지 않습니다. 그래서 검색해 봤는데 뜻밖의 글이 나오는군요. ^^
Dispatcher.BeginInvoke: Cannot convert lambda to System.Delegate
; http://stackoverflow.com/questions/4936459/dispatcher-begininvoke-cannot-convert-lambda-to-system-delegate
그러니까, "System.Windows.Presentation" 어셈블리를 참조한 후, "using System.Windows.Threading;" 선언을 추가하면 BeginInvoke에 Action을 받도록 하는 확장 메서드가 포함되기 때문에,
namespace System.Windows.Threading
{
public static class DispatcherExtensions
{
public static DispatcherOperation BeginInvoke(this Dispatcher dispatcher, Action action);
public static DispatcherOperation BeginInvoke(this Dispatcher dispatcher, Action action, DispatcherPriority priority);
public static void Invoke(this Dispatcher dispatcher, Action action);
public static void Invoke(this Dispatcher dispatcher, Action action, DispatcherPriority priority);
public static void Invoke(this Dispatcher dispatcher, Action action, TimeSpan timeout);
public static void Invoke(this Dispatcher dispatcher, Action action, TimeSpan timeout, DispatcherPriority priority);
}
}
이렇게 호출하는 코드가 정상적으로 컴파일이 됩니다.
this.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("TEST");
});
하지만, 보는 바와 같이 Action에 인자 전달을 받는 것은 확장 메서드로 재정의되어 있지 않기 때문에 다음과 같은 코드의 경우 여전히 오류가 발생합니다.
// error CS1660: Cannot convert lambda expression to type 'DispatcherPriority' because it is not a delegate type
this.Dispatcher.BeginInvoke((arg) =>
{
MessageBox.Show("TEST");
}, this);
위와 같이 인자를 전달하려면 어쩔 수 없이 명시적인 Action 형 변환을 해야만 합니다.
using System.Windows;
using System.Windows.Threading;
namespace WpfApp1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Dispatcher.BeginInvoke((System.Action<object>)((arg) =>
{
MessageBox.Show("TEST");
}), this);
// 또는,
this.Dispatcher.BeginInvoke((System.Action<MainWindow>)((arg) =>
{
MessageBox.Show("TEST");
}), this);
}
}
}
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]