سؤال

لماذا لا يمكنك تمرير طريقة مجهول كمعلمة إلى أسلوب 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()؟

و(أن تكون قادرة على القيام بذلك من شأنه أن يصلح في تماما مع مفهوم استخدام أساليب حالا / 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
    }
}
هل كانت مفيدة؟

المحلول

وجرب هذا:

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 */
    }
}

نصائح أخرى

ويجب أن تكون قادرا على كتابة شيء من هذا القبيل:

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
    }
}

هل يمكن كتابة طريقة التمديد التي من شأنها أن التفاف طرق مجهولة، وحتى تأخذ الرعاية من دلالات 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); });

ويمكنك القيام بذلك في أسلوب واحد من خلال الدعوة استدعاء نفسك:

  ClassData updData =  new ClassData();

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

...

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

لطرق مجهولة تماما مع عدد محدود من المعلمات:

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

ويمكنك استخدام أحد أنواع مندوب وظائفها الأخرى حسب الحاجة.

ولقد حاولت مجموعة من أساليب مختلفة ولكن العمل لا شيء. أي ...


// 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 لجعله أكثر إتقانا بعض الشيء ولكن هذا الى حد كبير ذلك.

وتحرير: تبين أن أكون مخطئا. يعمل الجواب methodinvoker أدناه. انظر هذا الصفحة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top