2011-01-02 12 views
13

が必要です。メソッドを表示するリストボックス(属性別)を持つwinフォームアプリケーションがあります。私はスレッド内のメソッドを動的に呼び出そうとしています。リフレクションを使用してリストボックスの選択された値からメソッド情報を取得しようとしています。しかし、Methodinfo.Invokeを呼び出すときに、この内部例外「非静的メソッドにはターゲットC#が必要です」が表示されます。非スタティックメソッドにはターゲットC#

ここに私のコードは、(私は一般的にはまだC#とプログラミングに新たなんだ覚えておいてください。)

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

答えて

19

あなたはどのこの方法のために、オブジェクトのインスタンスの参照を設けることなく、非静的メソッドを呼び出すようにしようとしているのです呼び出される必要があります。あなたがMainFormクラスのメソッドを使用して作業しているので、あなたの場合には、MethodInfo.Invoke(Object, Object[])の最初のパラメータにMainForm型のオブジェクトを提供する必要があります:

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

ありがとう:別のスレッドでメソッドを実行する

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

例迅速な対応のために。このコードを試した後、UIthreadではなくメインフォームのスレッドで選択されたメソッドを呼び出します。 (これらのスレッド名はあいまいですが、残念です)。 –

+0

あなたは 'testListBox.BeginInvoke()'を使ってmainformスレッド上で明示的にこのメソッドを呼び出しています。 'MethodInfo.Invoke()'は、それが呼び出されたスレッド上で実行されます。 – max

+0

ああ、私は参照してください。まあ、それは私のコードを再考する必要がありますように見えます。選択したメソッドをメインフォームとは別のスレッドで呼び出す方法について考えていますか? –

関連する問題