2011-01-02 14 views
13

Ich habe eine Win-Form-App mit einer Listbox Anzeige von Methoden (nach Attribut). Ich versuche, Methoden in einem Thread dynamisch aufzurufen und verwende Reflektion, um Methodeninformationen vom ausgewählten Wert des Listenfelds abzurufen. Beim Aufruf von Methodinfo.Invoke bekomme ich diese innere Ausnahme "Nicht-statische Methode erfordert ein Ziel C#".Nicht-statische Methode erfordert ein Ziel C#

meinen Code Hier ist (halte ich bin noch neu in C# und Programmierung im Allgemeinen. Im Auge)

private void PopulateComboBox() 
{//Populates list box by getting methods with declared attributes 
    MethodInfo[] methods = typeof(MainForm).GetMethods(); 

    MyToken token = null; 
    List<KeyValuePair<String, MethodInfo>> items = 
     new List<KeyValuePair<string, MethodInfo>>(); 

    foreach (MethodInfo method in methods) 
    { 
     token = Attribute.GetCustomAttribute(method, 
      typeof(MyToken), false) as MyToken; 
     if (token == null) 
      continue; 

     items.Add(new KeyValuePair<String, MethodInfo>(
      token.DisplayName, method)); 

    } 

    testListBox.DataSource = items; 
    testListBox.DisplayMember = "Key"; 
    testListBox.ValueMember = "Value"; 
} 

public void GetTest() 
{//The next two methods handle selected value of the listbox and invoke the method. 

    if (testListBox.InvokeRequired) 
     testListBox.BeginInvoke(new DelegateForTest(functionForTestListBox)); 
    else 
     functionForTestListBox(); 

} 

public void functionForTestListBox() 
{ 
    _t = testListBox.SelectedIndex; 

    if (_t < 0) 
     return; 

    _v = testListBox.SelectedValue; 

    method = _v as MethodInfo; 


    if (method == null) 
     return; 

    _selectedMethod = method.Name; 

    MessageBox.Show(_selectedMethod.ToString()); 

    method.Invoke(null, null);//<----Not sure about this. it runs fine when I dont invoke in a thread. 

    counter++; 

} 
private void runTestButton_Click(object sender, EventArgs e) 
{// Click event that calls the selected method in the thread 
    if (_serverStatus == "Running") 
    { 

     if (_testStatus == "Not Running") 
     { 

      // create Instance new Thread and add function 
      // which will do some work 
      try 
      { 
       SetupTestEnv(); 
       //functionForOutputTextBox(); 
       Thread UIthread = new Thread(new ThreadStart(GetTest)); 
       UIthread.Name = "UIThread"; 
       UIthread.Start(); 
       // Update test status 
       _testStatus = "Running"; 
       //Make thread global 
       _UIthread = UIthread; 
      } 
      catch 
      { 
        MessageBox.Show("There was an error at during the test setup(Note: You must install each web browser on your local machine before attempting to test on them)."); 
      } 

     } 
     else 
     { 
      MessageBox.Show("Please stop the current test before attempt to start a new one"); 
     } 
    } 
    else 
    { 
     MessageBox.Show("Please make sure the server is running"); 
    } 
} 

Antwort

19

Sie versuchen, nicht-statische Methode aufzurufen, ohne Objektinstanz bezugsbildenden, für die dieses Verfahren sollte aufgerufen werden. Da Sie mit den Methoden der MainForm Klasse arbeiten, sollten Sie Aufgabe MainForm Typ im ersten Parameter von MethodInfo.Invoke(Object, Object[]), in Ihrem Fall bieten:

if(method.IsStatic) 
    method.Invoke(null, null); 
else 
    method.Invoke(this, null); 

Beispiel für Verfahren auf separaten Thread ausführen:

public MethodInfo GetSelectedMethod() 
{ 
    var index = testListBox.SelectedIndex; 
    if (index < 0) return; 
    var value = testListBox.SelectedValue; 
    return value as MethodInfo; 
} 

private void ThreadProc(object arg) 
{ 
    var method = (MethodInfo)arg; 
    if(method.IsStatic) 
     method.Invoke(null, null) 
    else 
     method.Invoke(this, null); 
} 

private void RunThread() 
{ 
    var method = GetSelectedMethod(); 
    if(method == null) return; 
    var thread = new Thread(ThreadProc) 
    { 
     Name = "UIThread", 
    }; 
    thread.Start(method); 
} 
+0

Dank für die schnelle Antwort. Nach dem Ausprobieren dieses Codes wird jedoch die ausgewählte Methode im mainform-Thread und nicht im UIthread aufgerufen. (Diese Thread-Namen sind mehrdeutig, sorry darüber). –

+0

Sie rufen diese Methode explizit im mainform-Thread auf, indem Sie 'testListBox.BeginInvoke()' verwenden. 'MethodInfo.Invoke()' führt auf dem Thread aus, von dem es aufgerufen wurde. – max

+0

Ah ich sehe. Nun, es sieht so aus, als müsste ich meinen Code überdenken. Haben Sie irgendwelche Ideen, wie ich die gewählte Methode in einem anderen Thread als dem Hauptformular aufrufen könnte? –

Verwandte Themen