Programing

Control.BeginInvoke에 대한 MethodInvoker 대 작업

crosscheck 2020. 12. 29. 07:39
반응형

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");
}); 

나는 같은 일을하고있는 것 같은 느낌이 든다. 그렇다면 MethodInvokervs 를 사용 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

반응형