Ada*_*dam 1 c# variables multithreading global-variables
获取错误:跨线程操作无效:控制'label1'从其创建的线程以外的线程访问.
码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
string CONNECTING = "Connecting to server...";
string GETTING_DATA = "Getting data...";
string CONNECT_FAIL = "Failed to connect!";
string CONNECT_SUCCESS = "Connection established!";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Thread t1 = new Thread(run);
t1.Start();
}
public void run() {
label1.Text = CONNECTING;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我该如何正确解决这个问题?我尝试过使用CheckForIllegalCrossThreadCalls = false;但显然会导致错误.
我也想知道如何阻止线程,因为它不能在该函数之外被访问.
提前致谢!
尝试使用BeginInvoke:
public void run()
{
label1.BeginInvoke(new Action(() =>
{
label1.Text = CONNECTING;
}));
}
Run Code Online (Sandbox Code Playgroud)
只有UI线程可以更新Windows窗体应用程序中的UI元素.其他线程需要使用BeginInvoke来更新UI.
ORGINAL:我认为这是一个WPF应用程序,并说使用this.Dispatcher,但Dispatcher不在Windows Forms应用程序中.
您只能从创建的线程中WinForms App直接访问它。Control要执行此类任务,您需要使用控件的InvokeRequired属性来查看是否必须使用Invoke才能强制从原始线程调用操作。
可以从任何线程(包括原始线程)访问的公共方法如下所示:
public void run() {
if (label1.InvokeRequired) //Is this method being called from a different thread
this.Invoke(new MethodInvoker(()=> label1.Text = CONNECTING));
else //it's cool, this is the original thread, procceed
label1.Text = CONNECTING;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您绝对确定该run()方法只会从线程中调用,请考虑甚至不检查是否InvokeRequired并立即调用Invoke
更多信息:http://msdn.microsoft.com/en-us/library/ms171728 (v=vs.80 ).aspx
简单的就是使用t1.Abort(); 的方法Thread. 这将引发异常,迫使其停止在原来的位置。这对于不进行任何长时间处理的线程来说非常有用,因此停止它不会导致任何问题。
如果您确实在线程中进行处理,这意味着您不能只是在中间停止它,那么我建议您使用一个布尔值来指示线程必须尽快取消。
private bool isCancelRequired = false;
public void run() {
while(true) {
//do long processing..
if (isCancelRequired)
break;
}
}
Run Code Online (Sandbox Code Playgroud)