我有相当多的编程知识,但这是我第一次在C#上的多线程应用程序上工作,所以我在寻求有关我的问题的帮助。C#从UI线程操纵线程
首先,代码,
public frmCEX()
{
InitializeComponent();
refreshTicker();
}
private void btnRefresh_Click(object sender, EventArgs e)
{
refreshTicker();
}
private void refreshTicker()
{
ssStatus.Text = "Updating ticker..";
btnRefresh.Text = "Updating";
btnRefresh.Enabled = false;
ssUpdated.Text = "Last updated: -";
APIManager apim = new APIManager();
Ticker tk = apim.getTicker();
//blablabla, do some work
ssUpdated.Text = "Last updated: " + DateTime.Now.ToString();
ssStatus.Text = "";
btnRefresh.Text = "Refresh";
btnRefresh.Enabled = true;
}
private void cbxRefresh_CheckedChanged(object sender, EventArgs e)
{
if (cbxRefresh.Checked)
{
Thread thread1 = new Thread(() => BGRefreshThread(Convert.ToInt32(nupRefreshSecs.Value)));
thread1.Start();
}
else
{
// IF REFRESH CHECKBOX IS UNCHECKED, STOP THE THREAD THAT IS REFRESHING
}
}
private void BGRefreshThread(int delay)
{
refreshTicker();
System.Threading.Thread.Sleep(delay * 1000);
}
我的主要问题是在cbxRefresh_CheckedChanged
方法,基本上,这是如何工作的,当用户选中“自动刷新”复选框,在主界面中,的CheckedChanged方法将创建一个新线程BGRefreshThread
,它在后台运行并刷新股票代码,一旦该复选框再次被取消选中,它将结束刷新股票代码的线程。
但是,一旦启动后,我遇到了结束该线程的问题,因为一旦checkedchanged
方法结束,下一次未选中该复选框时,线程将不再存在于上下文中。
任何人都可以建议我可以得到这个工作吗?真的是新的多线程编程。
**编辑:我发现了这个问题的解决方案,但现在,当新创建的线程尝试调用“refreshTicker”更新主UI上的标签和按钮(主线程上) ,它给了我这个错误:
Cross-thread operation not valid: Control 'btnRefresh' accessed from a thread other than >the thread it was created on.
对此有何建议**
将线程1存储在更高的范围内?使用信令,使用该任务库。 –
您不能从UI线程以外的其他线程访问任何UI控件,您需要使用Control.Invoke或分派器。请参阅[这里](http://stackoverflow.com/questions/5037470/cross-thread-operation-not-valid)了解更多信息 –
谢谢!我改变了“refreshTicker();”到“this.Invoke((MethodInvoker)委托(){refreshTicker();});”但股票仍似乎没有刷新,似乎线程没有运行,出于某种原因。 – InnovativeDan