2013-05-13 2 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

+0

+1 "* 해당 서식있는 텍스트 상자에도 액세스하는 다른 방법이 없다고 가정합니다."*. RTB에 영향을 미치는 여러 가지 방법이있는 경우 같은 키를 사용하여 모두에 대해 lock 문이 필요합니다 (Servy가 지적한 * "사용자가 잠그는 개체는 모든 개체에 액세스 할 수 있습니다"). 그렇다고해서 다른 사람 (귀하의 바보 미래 포함)이 RTB에 접속하여 액세스하는 것을 막을 수는 없습니다. – JDB

+0

고마워, 나는 그것이 효과가 있다고 생각 :) 나는 여러 가지 방법으로 작업을 할 수 있지만 같은 잠금 개체를 사용하는 한 내가 잘해야한다? @ 케빈, 그냥 RTB를 잠그면 다른 호출이 첫 호출 이후에 액세스 할 수 있다고 생각하는 것과 같은 문제가 생깁니다. – CeeRo

관련 문제