我有一个场景.(Windows Forms,C#,.NET)
UserControl_Load方法,则UI在加载方法执行的持续时间内变得无响应.伪代码看起来像这样:
代码1
UserContrl1_LoadDataMethod()
{
if (textbox1.text == "MyName") // This gives exception
{
//Load data corresponding to "MyName".
//Populate a globale variable List<string> which will be binded to grid at some later stage.
}
}
Run Code Online (Sandbox Code Playgroud)
它给出的例外是
跨线程操作无效:从创建它的线程以外的线程访问控件.
为了更多地了解这一点,我做了一些谷歌搜索,并提出了一个建议,如使用下面的代码
代码2
UserContrl1_LoadDataMethod()
{
if (InvokeRequired) // Line #1
{
this.Invoke(new MethodInvoker(UserContrl1_LoadDataMethod));
return;
}
if (textbox1.text == "MyName") // Now it wont give an exception
{
//Load data correspondin to "MyName"
//Populate a globale …Run Code Online (Sandbox Code Playgroud) 只是想知道BeginInvoke()和之间的区别Invoke()是什么?
主要是每个人将用于什么.
编辑:创建一个线程对象和调用invoke并只调用BeginInvoke()一个委托有什么区别?或者他们是一样的吗?
我最近更新了一个从VS2003到VS2008的应用程序,我知道我将处理一系列"跨线程操作无效:控制'myControl'从一个线程访问,而不是它创建的线程"我在处理这个我所信奉的是正确的方法(参见下面的代码示例).我遇到了许多需要类似修复的控件.不希望为非UI线程访问的每个标签,文本框等都有类似的代码.仅为整个应用设置CheckForIllegalCrossThreadCalls = false会产生什么影响?
我找到了一个CodeProject文章,其中包含各种变通方法,并在底部发出警告,未设置该属性.我正在寻找关于这个问题的其他意见/经验.
private void ShowStatus(string szStatus)
{
try
{
if (this.statusBar1.InvokeRequired) { BeginInvoke(new MethodInvoker(delegate() { ShowStatus(szStatus); })); }
else { statusBar1.Panels[0].Text = szStatus; }
}
catch (Exception ex)
{
LogStatus.WriteErrorLog(ex, "Error", "frmMNI.ShowStatus()");
}
}
Run Code Online (Sandbox Code Playgroud)
我发现另一篇文章提出了一些可能的解决方案SO Question 2367718
我一直在使用Progress<T>,想知道是否可以将其替换Action<T>。
在下面的代码中,使用它们中的每个来报告进度(即ReportWithProgress()或)ReportWithAction()对我没有任何明显的影响。如何progressBar1增加字符串,如何将字符串写入输出窗口,它们看起来是相同的。
// WinForm application with progressBar1
private void HeavyIO()
{
Thread.Sleep(20); // assume heavy IO
}
private async Task ReportWithProgress()
{
IProgress<int> p = new Progress<int>(i => progressBar1.Value = i);
for (int i = 0; i <= 100; i++)
{
await Task.Run(() => HeavyIO());
Console.WriteLine("Progress : " + i);
p.Report(i);
}
}
private async Task ReportWithAction()
{
var a = new Action<int>(i => progressBar1.Value = i);
for (int i …Run Code Online (Sandbox Code Playgroud) 我试过这个。 /sf/answers/9944861/
喜欢 toolStripStatusLabel1.InvokeRequired
但toolStripStatusLabel1没有InvokeRequired
我也试过这个。 /sf/answers/1108190471/
它像无效参数一样出错
SetTextCallback d = new SetTextCallback(SetText);
form.Invoke(d, new object[] { form, ctrl, text });
当我使用
ThreadHelperClass.SetText(this, toolStripStatusLabel1, "This text was set safely.");
但我使用时不会出错 textBox
我的代码有方法等待bool另一个使用线程在后台运行的方法。
Thread t = new Thread(TestRemoteDB);
t.Start();
// In TestRemoteDB() will call updateRemoteDBStatus()
Run Code Online (Sandbox Code Playgroud)
像这样
private void updateRemoteDBStatus(bool successful)
{
if (successful)
{
toolStripStatusLabel4.Text = "OK!";
toolStripStatusLabel4.ForeColor = Color.Green;
}
else
{
toolStripStatusLabel4.Text = "Error!";
toolStripStatusLabel4.ForeColor = Color.Red;
}
}
Run Code Online (Sandbox Code Playgroud) 我需要一些帮助。我开始使用 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 …Run Code Online (Sandbox Code Playgroud)