以下代码给出了以下错误。我想我需要“InvokeRequired”。但我不明白我该怎么用?
跨线程操作无效:控制'listBox1'从其创建的线程以外的线程访问。
代码:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected static DataSet dataset = null;
private void Form1_Load(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
SimulationFrameWork.MCSDirector run = new SimulationFrameWork.MCSDirector();
DataSet ds = run.Get();
if (ds.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
if (ds.Tables[0].Rows[i]["result"].ToString() == "0")
{
dataset = run.Get(int.Parse(ds.Tables[0].Rows[i]["ID"].ToString()));
WorkerObject worker =
new WorkerObject(
int.Parse(dataset.Tables[0].Rows[i]["ID"].ToString()),
int.Parse(dataset.Tables[0].Rows[i]["Iteration"].ToString()),
listBox1, timer1);
Thread thread1 = new Thread(new ThreadStart(worker.start));
thread1.Start();
}
}
}
}
}
public class WorkerObject
{
private int id;
private int nmax;
private ListBox list1;
private System.Windows.Forms.Timer timer1;
public WorkerObject(int _id, int _nmax, ListBox _list1,
System.Windows.Forms.Timer _timer1)
{
id = _id;
nmax = _nmax;
list1 = _list1;
timer1 = _timer1;
}
public void start()
{
timer1.Stop();
int i, idaire, j;
double pi = 0.0, x, y;
Random rnd = new Random();
for (i = 0; i < 100; i++)
{
idaire = 0;
for (j = 0; j < nmax; j++)
{
x = rnd.Next(1, 10000) / (double)10000;
y = rnd.Next(1, 10000) / (double)10000;
if (Math.Pow(x, 2) + Math.Pow(y, 2) <= 1.0)
idaire += 1;
}
pi = 4 * (double)idaire / (double)nmax;
nmax *= 10;
list1.Items.Add(
"Iterasyon:" +
nmax.ToString() +
" ----->" +
pi.ToString() +
"\n");
System.Threading.Thread.Sleep(100);
}
SimulationFrameWork.MCSDirector run = new SimulationFrameWork.MCSDirector();
run.Update(id, pi);
list1.Items.Add("\n\n islem bitti...");
}
}
}
答案 0 :(得分:15)
这应该让你解决它
private delegate void stringDelegate(string s);
private void AddItem(string s)
{
if (list1.InvokeRequired)
{
stringDelegate sd = new stringDelegate(AddItem);
this.Invoke(sd, new object[] { s });
}
else
{
list1.Items.Add(s);
}
}
只需调用AddItem,如果需要,这将使用委托调用add,否则它只会将项目直接添加到框中。
单稳
答案 1 :(得分:10)
只需封装将文本添加到列表框中另一种方法:
private void timer1_Tick(object sender, EventArgs e)
{
// ...
AddTextToListBox("\n\n işlem bitti...");
}
private void AddTextToListBox(string text)
{
if(list1.InvokeRequired)
{
list1.Invoke(new MethodInvoker(AddTextToListBox), new object[] { text });
return;
}
list1.Items.Add(text);
}
答案 2 :(得分:0)
也可以使用lambda表示法。所以,而不是:
formControl.Field = newValue; //Causes error
尝试:
Invoke(new Action(() =>
{
formControl.Field = newValue; //No error
}));
答案 3 :(得分:-5)
在开始主题之前添加此代码:
//kolay gelsin kardeş )
CheckForIllegalCrossThreadCalls = false;
thread1.Start();