2011-01-02 36 views
13

Tôi có ứng dụng biểu mẫu giành chiến thắng với hộp danh sách hiển thị các phương thức (theo thuộc tính). Tôi đang cố gắng tự động gọi các phương thức trong một luồng, sử dụng sự phản chiếu để lấy thông tin phương thức từ giá trị được chọn của hộp danh sách. Tuy nhiên, khi gọi Methodinfo.Invoke Tôi nhận được ngoại lệ bên trong này "Phương thức không tĩnh yêu cầu mục tiêu C#".Phương pháp không tĩnh yêu cầu mục tiêu C#

Dưới đây là mã của tôi (lưu ý tôi vẫn còn mới để C# và lập trình nói chung.)

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

Trả lời

19

Bạn đang cố gắng gọi phương thức không tĩnh mà không cung cấp tài liệu tham khảo trường hợp đối tượng, trong đó phương pháp này nên được gọi. Kể từ khi bạn đang làm việc với các phương pháp của MainForm lớp, bạn nên cung cấp đối tượng của MainForm gõ vào tham số đầu tiên của MethodInfo.Invoke(Object, Object[]), trong trường hợp của bạn:

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

Ví dụ về phương pháp thực hiện trên thread riêng biệt:

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

Cảm ơn cho phản ứng nhanh. Sau khi thử mã này mặc dù, nó sẽ gọi phương thức được chọn trên luồng mainform chứ không phải UIthread. (Những tên chủ đề là mơ hồ, xin lỗi về điều đó). –

+0

Bạn đang gọi phương thức này một cách rõ ràng trên chuỗi chủ đề chính bằng cách sử dụng 'testListBox.BeginInvoke()'. 'MethodInfo.Invoke()' thực hiện trên luồng mà từ đó nó được gọi. – max

+0

Tôi hiểu rồi. Có vẻ như tôi sẽ phải suy nghĩ lại mã của mình. Bạn có bất kỳ ý tưởng về cách tôi có thể đi về việc chọn phương pháp được chọn để gọi trong một chủ đề khác với hình thức chính? –

Các vấn đề liên quan