Control.BeginInvoke에 대한 MethodInvoker 대 작업
어느 것이 더 정확하고 그 이유는 무엇입니까?
Control.BeginInvoke(new Action(DoSomething), null);
private void DoSomething()
{
MessageBox.Show("What a great post");
}
또는
Control.BeginInvoke((MethodInvoker) delegate {
MessageBox.Show("What a great post");
});
나는 같은 일을하고있는 것 같은 느낌이 든다. 그렇다면 MethodInvoker
vs 를 사용 Action
하거나 심지어 람다 식을 작성 하기에 적절한시기는 언제 인가?
편집 : 나는 람다 작성과 람다 작성 사이에 큰 차이가 없다는 것을 알고 Action
있지만 MethodInvoker
특정 목적을 위해 만들어진 것 같습니다. 다른 일을하고 있습니까?
둘 다 똑같이 정확하지만 문서에는 Control.Invoke
다음과 같은 내용이 나와 있습니다.
대리자는 EventHandler의 인스턴스 일 수 있으며,이 경우 sender 매개 변수에는이 컨트롤이 포함되고 이벤트 매개 변수에는 EventArgs.Empty가 포함됩니다. 대리자는 MethodInvoker의 인스턴스이거나 void 매개 변수 목록을 사용하는 다른 대리자 일 수도 있습니다. EventHandler 또는 MethodInvoker 델리게이트에 대한 호출은 다른 유형의 델리게이트에 대한 호출보다 빠릅니다.
따라서 MethodInvoker
더 효율적인 선택이 될 것입니다.
아래 각 솔루션에 대해 131072 (128 * 1024) 반복 (하나의 분리 된 스레드에서)을 실행합니다. VS2010 성능 도우미는 다음과 같은 결과를 제공합니다.
- 읽기 전용 MethodInvoker : 5664.53 (+ 0 %)
- 새로운 MethodInvoker : 5828.31 (+ 2.89 %)
- MethodInvoker의 함수 캐스트 : 5857.07 (+ 3.40 %)
- 읽기 전용 액션 : 6467.33 (+ 14.17 %)
- 새로운 액션 : 6829.07 (+ 20.56 %)
반복 할 때마다 새 작업 호출
private void SetVisibleByNewAction()
{
if (InvokeRequired)
{
Invoke(new Action(SetVisibleByNewAction));
}
else
{
Visible = true;
}
}
읽기 전용, 빌드 인 생성자, 각 반복에서 작업 호출
// private readonly Action _actionSetVisibleByAction
// _actionSetVisibleByAction= SetVisibleByAction;
private void SetVisibleByAction()
{
if (InvokeRequired)
{
Invoke(_actionSetVisibleByAction);
}
else
{
Visible = true;
}
}
반복 할 때마다 새 MethodInvoker 를 호출합니다 .
private void SetVisibleByNewMethodInvoker()
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(SetVisibleByNewMethodInvoker));
}
else
{
Visible = true;
}
}
각 반복에서 읽기 전용, 빌드 인 생성자, MethodInvoker 에 대한 호출
// private readonly MethodInvoker _methodInvokerSetVisibleByMethodInvoker
// _methodInvokerSetVisibleByMethodInvoker = SetVisibleByMethodInvoker;
private void SetVisibleByMethodInvoker()
{
if (InvokeRequired)
{
Invoke(_methodInvokerSetVisibleByMethodInvoker);
}
else
{
Visible = true;
}
}
반복 할 때마다 MethodInvoker 의 함수 캐스트 호출
private void SetVisibleByDelegate()
{
if (InvokeRequired)
{
Invoke((MethodInvoker) SetVisibleByDelegate);
}
else
{
Visible = true;
}
}
"New Action"솔루션 호출의 예 :
private void ButtonNewActionOnClick(object sender, EventArgs e)
{
new Thread(TestNewAction).Start();
}
private void TestNewAction()
{
var watch = Stopwatch.StartNew();
for (var i = 0; i < COUNT; i++)
{
SetVisibleByNewAction();
}
watch.Stop();
Append("New Action: " + watch.ElapsedMilliseconds + "ms");
}
나는 람다와 액션 / 펑크를 선호한다.
Control.BeginInvoke(new Action(() => MessageBox.Show("What a great post")));
Action은 System에 정의되어 있고 MethodInvoker는 System.Windows.Forms에 정의되어 있습니다. Action은 다른 위치로 이동할 수 있기 때문에 Action을 사용하는 것이 좋습니다. 또한 MethodInvoker보다 Action을 매개 변수로 허용하는 더 많은 위치를 찾을 수 있습니다.
However, the documentation does indicate that calls to delegates of type EventHandler or MethodInvoker in Control.Invoke() will be faster than any other type.
Aside from which namepsace they are in, I don't believe there is a meaningful functional difference between Action and MethodInvoker - they are essentially both defined as:
public delegate void NoParamMethod();
As an aside, Action has several overloads which allow parameters to be passed in - and it is generic so that they can be typesafe.
Also per MSDN:
MethodInvoker provides a simple delegate that is used to invoke a method with a void parameter list. This delegate can be used when making calls to a control's Invoke method, or when you need a simple delegate but do not want to define one yourself.
an Action on the other hand can take up to 4 parameters.
But I don't think there is any difference between MethodInvoker and Action as they both simply encapsulate a delegate that doesn't take a paremter and returns void
If you look at their definitions you'll simply see this.
public delegate void MethodInvoker();
public delegate void Action();
btw you could also write your second line as.
Control.BeginInvoke(new MethodInvoker(DoSomething), null);
It is a matter of preference in most cases, unless you intend to reuse the DoSomething() method. Also the anonymous functions will place your scoped variables on the heap, might make it a more expensive function.
Don't forget to somehow check if control is available at the moment, to avoid errors at closing form.
if(control.IsHandleCreated)
control.BeginInvoke((MethodInvoker)(() => control.Text="check123"));
ReferenceURL : https://stackoverflow.com/questions/1167771/methodinvoker-vs-action-for-control-begininvoke
'Programing' 카테고리의 다른 글
Python int를 빅 엔디안 바이트 문자열로 변환 (0) | 2020.12.29 |
---|---|
SOA (서비스 지향 아키텍처) 란 무엇입니까? (0) | 2020.12.29 |
ListView 항목이 콘텐츠를 래핑하기 위해 커지지 않는 이유는 무엇입니까? (0) | 2020.12.29 |
CTE 오류 : "앵커와 재귀 부분간에 유형이 일치하지 않습니다." (0) | 2020.12.29 |
스위치 블록 내에서 foreach 루프에서 벗어나기 (0) | 2020.12.29 |