EDIT2 : 이것은 단순한 크로스 스레드 문제가 아닙니다. 위의 링크를 기반으로 컨트롤을 업데이트 할 수 있지만 Cursor 또는 toolStrip에서는 작동하지 않습니다. 작동하지 않는다는 것은 작동하지 않는다는 것을 의미합니다. 컨트롤을 다른 스레드에서 만들어서 수정할 수 없다는 일반적인 오류 메시지가 나타납니다. Invoke는 toolStrip에 대한 옵션이 아닙니다.별도의 스레드에서 작업이 완료 될 때 트리거하는 방법은 무엇입니까?
버튼 클릭시 별도의 스레드에서 일부 작업을 시작합니다. 시간이 걸릴 수 있고 양식이 보통 얼어 붙는 것이 필요합니다. 내 문제는 내가 몇 가지 컨트롤을 수정하고 끝에 작업자 스레드에서 할 수 없어 그들을 다시 설정해야한다는 것입니다. 어떻게 해결할 수 있을까요?
private void button1_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
toolStripStatusLabel1.Text = "Working...";
Thread thread = new Thread(query);
thread.Start();
}
private void query()
{
//actions
//here I need to set the cursor back to default
Cursor.Current = Cursors.Default; //but this is obviously not working
//and I have to set the label text to be "done"
//which is not working as well as invoke is not an option for toolStrips
}
그래서 위의 작업을 수행하려면 해결책이 필요합니다. 어쩌면 일단 백그라운드 (backgroundworker)가 쿼리 (thread)와 액션 (action)이 끝나면 "눈을 떼지"않을 것입니다.
EDIT3 : 나는 ToolStrip에를 제외하고, 코드의 아래 부분에있는 컨트롤의 속성을 수정할 수 있습니다
delegate void SetControlValueCallback(Control oControl, string propName, object propValue);
private void SetControlPropertyValue(Control oControl, string propName, object propValue)
{
if (oControl.InvokeRequired)
{
SetControlValueCallback d = new SetControlValueCallback(SetControlPropertyValue);
oControl.Invoke(d, new object[] { oControl, propName, propValue });
}
else
{
Type t = oControl.GetType();
PropertyInfo[] props = t.GetProperties();
foreach (PropertyInfo p in props)
{
if (p.Name.ToUpper() == propName.ToUpper())
{
p.SetValue(oControl, propValue, null);
}
}
}
}
해결책 : 아이디어
private void query()
{
//actions
Invoke((Action)(() =>
{
Cursor.Current = Cursors.Default;
toolStripStatusLabel1.Text = "done";
}));
}
당신에게 마크 Gravell 감사합니다