Подтвердить что ты не робот

Анонимный метод как параметр для BeginInvoke?

Почему вы не можете передать анонимный метод в качестве параметра методу BeginInvoke? У меня есть следующий код:

private delegate void CfgMnMnuDlg(DIServer svr);
private void ConfigureMainMenu(DIServer server,)
{
    MenuStrip mnMnu = PresenterView.MainMenu;
    if (mnMnu.InvokeRequired)
    {
        mnMnu.BeginInvoke((CfgMnMnuDlg)ConfigureMainMenu, 
                            new object[] { server});
    }
    else
    {
        // Do actual work here
    }
}

Я пытаюсь избежать объявления делегата. Почему я не могу написать что-то вроде ниже? Или я могу, и я просто не могу понять правильный синтаксис? Ниже в настоящее время создается:

Тип аргумента "Анонимный метод" не присваивается типу параметра "System.Delegate"

Хорошо, это право, конечно, но есть ли другой синтаксис, который я могу использовать для этого (не нужно объявлять отдельный делегат, чтобы использовать BeginInvoke()?

(Возможность сделать это вписывается в концепцию использования методов anon/lamdas вместо явных делегатов, которые работают так чисто везде).

private void ConfigureMainMenu(DIServer server,)
{
    MenuStrip mnMnu = PresenterView.MainMenu;
    if (mnMnu.InvokeRequired)
    {
        mnMnu.BeginInvoke(  //  pass anonymous method instead ?
             delegate(DIServer svr) { ConfigureMainMenu(server);},     
             new object[] { server});
    }
    else
    {
        // Do actual work here
    }
}
4b9b3361

Ответ 1

Попробуйте следующее:

control.BeginInvoke((MethodInvoker) delegate { /* method details */ });

Или:

private void ConfigureMainMenu(DIServer server)
{
    if (control.InvokeRequired)
    {
        control.BeginInvoke(new Action<DIServer >(ConfigureMainMenu), server);
    }
    else
    {
        /* do work */
    }
}

Или:

private void ConfigureMainMenu(DIServer server)
{
    MenuStrip mnMnu = PresenterView.MainMenu;
    if (mnMnu.InvokeRequired)
    {
        // Private variable
        _methodInvoker = new MethodInvoker((Action)(() => ConfigureMainMenu(server)));
        _methodInvoker.BeginInvoke(new AsyncCallback(ProcessEnded), null); // Call _methodInvoker.EndInvoke in ProcessEnded
    }
    else
    {
        /* do work */
    }
}

Ответ 2

Вы должны написать что-то вроде этого:

private void ConfigureMainMenu(DIServer server,)
{
    MenuStrip mnMnu = PresenterView.MainMenu;
    if (mnMnu.InvokeRequired)
    {
        mnMnu.BeginInvoke(new Action<DIServer>(ConfigureMainMenu), 
                            new object[] { server});
    }
    else
    {
        // Do actual work here
    }
}

Ответ 3

Вы можете написать метод расширения, который бы обернул анонимные методы и даже позаботился о семантике InvokeRequired:

public static void InvokeAction(this Control ctl, Action a)
{
    if (!ctl.InvokeRequired)
    {
        a();
    }
    else
    {
        ctl.BeginInvoke(new MethodInvoker(a));
    }
}

Это позволит вам сделать:

control.InvokeAction(delegate() { ConfigureMainMenu(server); });

Ответ 4

Вы можете сделать это одним методом, вызвав вызов:

  ClassData updData =  new ClassData();

  this.BeginInvoke(new Action<ClassData>(FillCurve),
                           new object[] { updData });

...

public void FillCurve(ClassData updData)
{
 ...
}

Ответ 5

Я пробовал кучу разных методов, но никто не работал. то есть...


// Fails -- cannot convert lamda to System.Delegate
mnMnu.BeginInvoke( (DIServer svr)=> {ConfigureMainMenu(server);}, new object[] server);
// Fails -- cannot convert anonymous method to System.Delegate
mnMnu.BeginInvoke( new delegate(DIServer svr){ConfigureMainMenu(server);}, new object[] server);

Итак, короткий ответ - нет. Вы могли бы создать короткие помощники делегатов в данном контексте и использовать lambdas, чтобы сделать его немного опрятным, но это в значительной степени оно.

EDIT: Оказывается, я ошибаюсь. Ниже приведено нижеприведенное описание метода. Смотрите страница

Ответ 6

Для полностью анонимных методов с ограниченным числом параметров:

Func<int, int?> caller = new Func<int, int?>((int param1) =>
   {
      return null;
   });

caller.BeginInvoke(7, new AsyncCallback((IAsyncResult ar) =>
{
   AsyncResult result = (AsyncResult)ar;
   Func<int, int?> action = (Func<int, int?>)result.AsyncDelegate;
   action.EndInvoke(ar);
}), null);

При необходимости вы можете использовать один из других типов делегатов Func.