2013-05-13 53 views
2

鑑於以下代碼,我將如何鎖定richtextbox,以便每個日誌調用在另一個可以開始鍵入之前完成工作?鎖定從非UI線程調用的richtextboxes

private delegate void ReportLogDelegate(RichTextBox box, Color color, string message); 

public void FileLog(string file, string project, string type, string fileNr, string note) 
{ 
    if (type == "incoming") 
    { 
     this.Invoke(new ReportLogDelegate(this.AppendText), new object[] { logTextBox, Color.Orange, String.Format("{0} - {1}", DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString()) }); 
     string message = string.Format("\n\tFile Incoming\n\tFile: {0}\n\tProject: {1}\n\tFileNumber: {2}\n\n", file, project, fileNr); 
     this.Invoke(new ReportLogDelegate(this.AppendText), new object[] { logTextBox, Color.White, message }); 
    } 
    else if (type == "done") 
    { 
     this.Invoke(new ReportLogDelegate(this.AppendText), new object[] { logTextBox, Color.GreenYellow, String.Format("{0} - {1}", DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString()) }); 
     string message = string.Format("\n\tFile Received\n\tFile: {0}\n\tProject: {1}\n\tFileNumber: {2}\n\n", file, project, fileNr); 
     this.Invoke(new ReportLogDelegate(this.AppendText), new object[] { logTextBox, Color.White, message }); 
    } 
    else if (type == "error") 
    { 
     this.Invoke(new ReportLogDelegate(this.AppendText), new object[] { logTextBox, Color.Red, String.Format("{0} - {1}", DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString()) }); 
     string message = string.Format("\n\tError Receiving File\n\tFile: {0}\n\tProject: {1}\n\tFileNumber: {2}\n\tError: {3}\n\n", file, project, fileNr, note); 
     this.Invoke(new ReportLogDelegate(this.AppendText), new object[] { logTextBox, Color.Red, message }); 
    } 
} 


// Append text of the given color. 
void AppendText(RichTextBox box, Color color, string text) 
{ 
    int start = box.TextLength; 
    box.AppendText(text); 
    int end = box.TextLength; 

    // Textbox may transform chars, so (end-start) != text.Length 
    box.Select(start, end - start); 
    { 
     box.SelectionColor = color; 
     // could set box.SelectionBackColor, box.SelectionFont too. 
    } 
    box.SelectionLength = 0; // clear 
} 

每個對FileLog的調用應該允許在另一個訪問RTB之前運行到最後。

回答

4

只需將整個方法放入lock塊。創建一個新的私人對象鎖定,這樣就可以確保沒有其他方法都使用相同的同步鎖定:

private object key = new object(); 
public void FileLog(string file, string project, string type, string fileNr, string note) 
{ 
    lock(key) 
    { 
     //your existing implementation goes here 
    } 
} 

這是假設你沒有這也將訪問該豐富的任何其他方法文本框。如果你有其他人,那麼你需要確保你鎖定的對象可以被所有人訪問。

+1

爲什麼不鎖定RichTextBox? – Kevin 2013-05-13 16:10:01

+0

+1與條件*「假設您沒有任何其他方法,也將訪問該富文本框」*。如果你有多個影響RTB的方法,你需要使用相同的密鑰在所有的方法上使用鎖定語句(正如Servy指出的那樣:*「你鎖定的對象可以被所有對象訪問」*)。但是,這不會阻止其他人(包括你的白癡future-self)來訪問RTB。 – JDB 2013-05-13 16:15:52

+0

謝謝,我認爲這將工作:)我確實有多個方法在工作,但只要我使用相同的鎖對象,我應該是對的? @凱文,只是鎖定RTB會給我現在的問題,我現在認爲,第一次調用後,另一個電話將訪問它 – CeeRo 2013-05-13 16:15:57