eAg*_*gle 1 c# cloud multithreading delegates timer
我需要一些帮助。我开始使用 c#,但对事件处理和线程还不是很熟悉。作为一个初学者,随着时间和接触的增加,我想了解更多关于这些高级主题的知识并进行改进,并希望这里的所有人都能帮助我。
我遇到了“跨线程操作无效:从创建它的线程以外的线程访问控制‘名为 stackStatus’的文本框控件”的问题。我一整天都在尝试解决问题,但根本无济于事。我被困住了。:-( 程序遇到异常,无法继续顺利执行。
我已阅读以下主题并尝试了一些事情,但我想我仍然缺少一些东西。如果有人能在这里帮助我,我将不胜感激。谢谢。
跨线程操作无效:从创建它的线程以外的线程访问控制“textBox1”
这是代码的大部分部分:
private void createCloud_Click(object sender, EventArgs e)
{
CreateCloud(); //start creation method
stackStatus.Text = "Creating stack..."; //updates the cloud status textbox
stackStatus.Refresh();
Cursor.Current = Cursors.WaitCursor; //change the cursor to wait state
Start_Describestack(); //call describe method to find out the status of cloud creation progress
Task.Delay(12000); // wait 12s in case not ready
Start_Describestack(); // call again describe method to find out the cloud creation progress status
Cursor.Current = Cursors.Default; //put cursor on wait
describeevents(); // call method to get all cloud creation event data and publish on the datagridview
}
private void Start_Describestack()
{
//method making use of timer to call
_timer = new System.Timers.Timer(15000);
_timer.Elapsed += new ElapsedEventHandler(describeStack);
_timer.Enabled = true;
}
delegate void describeStackCallBack(object sender, ElapsedEventArgs e);
private void describeStack(object sender, ElapsedEventArgs e)
{
//this method makes api calls through cloudclient to describe the stack
//this is where the "Cross-thread operation not valid: Control 'stackStatus' accessed from a thread other than the thread it was created on"
var client = new cloudclient();
var request2 = new StacksRequest();
request2.Cloudstackname = stackid;
try
{
var response = client.DescribeCloudStacks(request2);
foreach (var stack in response.Stacks)
{
//something is wrong here but I do not know how to fix it. Please help
if (this.stackStatus.InvokeRequired)
{
describeStackCallBack d = new describeStackCallBack(describeStack);
this.Invoke(d, new object[] { sender, e });
stackStatus.Refresh();
describevents();
}
else
{
stackStatus.Text = stack.StackStatus;
stackStatus.Refresh();
describeevents();
}
}
}
catch (Exception)
{
if (this.stackStatus.InvokeRequired)
{
describeStackCallBack d = new describeStackCallBack(describeStack);
this.Invoke(d, new object[] { sender, e });
stackStatus.Text = "Stack not found/Deleted";
}
else
{ stackStatus.Text = "Stack not found/Deleted"; }
}
describeevents();
}
private void describeevents()
{
var newclient = new cloudclient();
var request3 = new eventrequest();
request3.Cloudstackname = stackid;
try
{
var response = newclient.eventstack(request3);
dataGridView3.Rows.Clear();
foreach (var events in response.sevents)
{
dataGridView3.Rows.Add(events.Timestamp, events.ResourceStatus, events.ResourceType);
}
}
catch (Exception)
{
dataGridView3.Rows.Clear();
MessageBox.Show("Stack not ready!");
}
dataGridView3.Refresh();
}
Run Code Online (Sandbox Code Playgroud)
Na*_*de 9
而不是做:
stackStatus.Text = "some text";
Run Code Online (Sandbox Code Playgroud)
尝试 :
stackStatus.Invoke((Action)delegate
{
stackStatus.Text = "some text";
});
Run Code Online (Sandbox Code Playgroud)
请注意,不推荐在声明它们的线程之外进行 GUI 元素分配,因为控件可能随时不再可用。