2012-03-23 128 views
1

我想學習委託,不知道我做錯了什麼。所以我有三個類,Form1,Class1和Class2。 Form1調用Class1方法爲Class1成員設置字符串,然後Form1啓動workerbackground線程以啓動Class2。但是,當Class2調用Form1委託方法將調用Class1方法來獲取字符串數據,但它返回爲Class2爲null。C#委託返回NULL

因此,這是它返回null,>>字符串str = form1Obj.gDelegateClass1GetData(();

這是Form1中:

public delegate string DelegateClass1GetData(); 
public delegate void DelegateClass1SetData(string data); 

public partial class Form1 : Form 
{ 
    public DelegateClass1GetData gDelegateClass1GetData; 
    public DelegateClass1SetData gDelegateClass1SetData; 

    public Class1 class1Obj; 
    public BackgroundWorker bw_Class2; 
    public Class2 class2Obj; 


    public Form1() 
    { 
     InitializeComponent(); 

     class1Obj = new Class1(); 
     class2Obj = new Class2(this); 


     gDelegateClass1GetData = new DelegateClass1GetData(this.Class1GetData); 
     gDelegateClass1SetData = new DelegateClass1SetData(this.Class1SetData); 
    } 


    private void button1_Click(object sender, EventArgs e) 
    { 
     class1Obj.setClass1Data("Hello"); 

     bw_Class2 = new BackgroundWorker(); 
     bw_Class2.WorkerSupportsCancellation = true; 

     bw_Class2.DoWork += new DoWorkEventHandler(ThreadClass2_DoWork); 
     bw_Class2.RunWorkerAsync(); 
    } 


    public string Class1GetData() 
    { 
     if (InvokeRequired) 
      Invoke(new DelegateClass1GetData(Class1GetData)); 
     else 
     { 
      return class1Obj.GetClass1Data(); 
     } 

     return null; 
    } 


    public void Class1SetData(string data) 
    { 
     if (InvokeRequired) 
      Invoke(new DelegateClass1SetData(Class1SetData), data); 
     else 
     { 
      class1Obj.setClass1Data(data); 
     } 
    } 


    public void ThreadClass2_DoWork(object sender, DoWorkEventArgs e) 
    { 
     string str1 = class1Obj.GetClass1Data(); 
     class2Obj.AddString(); 
    } 

} 

這是1類:

public class Class1 
{ 
    public string gClass1Data; 

    public Class1() 
    { 
     gClass1Data = null; 
    } 


    public void setClass1Data(string data) 
    { 
     gClass1Data = data; 
    } 


    public string GetClass1Data() 
    { 
     return gClass1Data; 
    } 
} 

本類2:

public class Class2 
{ 

    public Form1 form1Obj; 

    public Class2(Form1 obj) 
    { 
     form1Obj = obj; 
    } 


    public void AddString() 
    { 
     string str = form1Obj.gDelegateClass1GetData(); 
     str = str + " Delegate"; 

     form1Obj.gDelegateClass1SetData(str); 
     string str2 = form1Obj.gDelegateClass1GetData(); 
    } 
} 
+0

你有沒有嘗試在form1.Class1GetData()中看到什麼是斷點?如果invoke是必需的,那麼該方法將返回null。 – JamieB 2012-03-23 02:28:26

+0

是的我試着用斷點調試它,它顯示需要調用。不知道這意味着什麼,但會讀入它。謝謝。 – Lufia 2012-03-23 02:39:54

回答

2

問題在於Form1.Class1GetData方法。當您在Class2.AddString()中撥打form1Obj.gDelegateClass1GetData()時,實際上您會撥打Form1.Class1GetDataInvokeRequired返回true,您必須再次撥打Form1.Class1GetData。這一次,InvokeRequired返回false,你打電話class1Obj.GetClass1Data(),並返回「你好」。它實際上返回到第一個電話Form1.Class1GetData,但您最終返回null。所以,你得到nullstring str = form1Obj.gDelegateClass1GetData(();。嘗試修復它作爲

public string Class1GetData() 
{ 
    if (InvokeRequired) 
     return (string) Invoke(new DelegateClass1GetData(Class1GetData)); // return the first call to Class1GetData 
    else 
    { 
     return class1Obj.GetClass1Data(); 
    } 

    //return null; // Don't return null. 
} 
+0

感謝您一步一個腳印。但是,如果我刪除返回null,我會得到錯誤,因爲它不包括所有的返回路徑。我也試圖聲明局部變量,以便返回Class1Ojb.GetClass1Data(),我把變量字符串名稱= Class1Obj.GetClass1Data();然後在下面返回變量字符串名稱,但仍爲空。 – Lufia 2012-03-23 02:44:29

+1

@Lufia - 注意Invoke調用前面的'return(string)'。這是他指出的。在需要Invoke的情況下,它會調用,但會下降到您的'返回null'。這就是爲什麼你得到空值。 – Mufaka 2012-03-23 02:51:33

+0

哦哇!感謝您指出了這一點。我沒有看到代碼中的返回(字符串)。這是解決它,並感謝姚。 – Lufia 2012-03-23 02:58:34