2017-06-02 2 views
1

別のスレッドから要素にアクセスするにはどうすればよいですか?この場合、メインスレッド(GUI)にリッチテキストボックスがあり、セカンダリスレッドでメソッドを実行しています。私は、次のエラーが表示された二次スレッドを通じてC#他のスレッドからの要素へのアクセス

private void Log(string input, Label lbl) 
{ 
    lbl.Invoke(new Action(()=> 
    { 
     lbl.Text = "Status: " + input; 
     Thread.Sleep(50); 
    })); 
} 

void Run() 
{ 
    foreach (string line in richTextBox1.Lines) 
    { 
     Log(line, label1); 
     Thread.Sleep(500); 
    } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    ThreadStart th = new ThreadStart(() => Run()); 
    Thread th2 = new Thread(th); 
    th2.Start(); 
    //th2.Join(); 
} 

をricheditboxにアクセスしたい:

無効なスレッド操作:コントロールのrichTextBox1 "で、それ一つではない スレッドからアクセス作成されました。

+0

ここを見て:https://stackoverflow.com/questions/661561/how-to-update-the-gui-from-another-thread-in-c(私は考える44)がいくつかありますのここで答えます。個人的には、TAPベースのものが好きです。 – Kevin

答えて

1

これは既に実行しています。 Logメソッドが正しいことを示しています - Invokeを使用してUIスレッドでコードを実行してください。これは本当に必要ではない、しかし、

void Run() 
{ 
    var getLines = new Func<object>(() => richTextBox1.Lines); 
    var lines = (string[]) richTextBox1.Invoke(getLines); 
    foreach (var line in lines) 
    { 
     Log(line, label1); 
     Thread.Sleep(500); 
    } 
} 

:この場合は、あなたのような何かを行うことができます。ボタンをクリックしてバックグラウンドスレッドに渡すだけで、実際にLinesプロパティを1度読みたいようです。

void Run(string[] lines) 
{ 
    foreach (var line in lines) 
    { 
     Log(line, label1); 
     Thread.Sleep(500); 
    } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    var lines = richTextBox1.Lines; 
    var th = new ThreadStart(() => Run(lines)); 
    var th2 = new Thread(th); 
    th2.Start(); 
} 
+0

ありがとう、素晴らしい作品! –

+0

@Johnred:答えとして受け入れてください。 –

0

これは別のバージョンです...あなたはUIスレッドで実行されているLog()メソッドでスリープ状態にしてはいけません。

private void button1_Click(object sender, EventArgs e) 
{ 
    ThreadStart th = new ThreadStart(() => Run()); 
    Thread th2 = new Thread(th); 
    th2.Start(); 
} 

void Run() 
{ 
    string[] lines = (string[])richTextBox1.Invoke(new Func<string[]>(() => richTextBox1.Lines)); 
    foreach (string line in lines) 
    { 
     Log(line, label1); 
     Thread.Sleep(500); 
    } 
} 

private void Log(string input, Label lbl) 
{ 
    lbl.Invoke(new Action(() => 
    { 
     lbl.Text = "Status: " + input; 
    })); 
} 
関連する問題