C# 使用backgroundworker同时向下移动2个标签
这是我的代码,但是label1比label2先运行?我想要的是在label1和label2各自的线程上同时运行它们。顺便说一句,我使用过线程,但它不能访问控件,除非在它自己的线程中创建它。所以在这段代码中,当我创建实例时,比如:C# 使用backgroundworker同时向下移动2个标签,c#,multithreading,label,backgroundworker,move,C#,Multithreading,Label,Backgroundworker,Move,这是我的代码,但是label1比label2先运行?我想要的是在label1和label2各自的线程上同时运行它们。顺便说一句,我使用过线程,但它不能访问控件,除非在它自己的线程中创建它。所以在这段代码中,当我创建实例时,比如:Slave s1=newslave(label1);从机s2=新的从机(标签2)它将自动开始移动两个标签,但不会移动 public class Slave { private Label l; private BackgroundWorker bw;
Slave s1=newslave(label1);从机s2=新的从机(标签2)代码>它将自动开始移动两个标签,但不会移动
public class Slave
{
private Label l;
private BackgroundWorker bw;
public Slave(Label l)
{
this.l = l;
bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork+=new DoWorkEventHandler(worknow);
bw.ProgressChanged += new ProgressChangedEventHandler(update);
bw.RunWorkerAsync();
}
private void worknow(object sender, DoWorkEventArgs e)
{
BackgroundWorker b = sender as BackgroundWorker;
b.ReportProgress(1);
}
private void update(object sender, ProgressChangedEventArgs e)
{
for(int x=0; x<20;x++)
{
l.Top += 10;
System.Threading.Thread.Sleep(100);
}
}
}
公共类从属
{
自有品牌l;
私人背景工作者;
公共奴隶(标签l)
{
这个。l=l;
bw=新的BackgroundWorker();
bw.WorkerReportsProgress=true;
bw.DoWork+=新的DoWorkEventHandler(worknow);
bw.ProgressChanged+=新的ProgressChangedEventHandler(更新);
RunWorkerAsync();
}
私有void worknow(对象发送方,DoWorkEventArgs e)
{
BackgroundWorker b=发送方作为BackgroundWorker;
b、 报告进展(1);
}
私有无效更新(对象发送方,ProgressChangedEventArgs e)
{
对于(int x=0;x好的,我刚刚找到了问题的解决方案,所以我会回答我自己的问题,所以我有一个winform,有一个面板和一个按钮,非常简单,所以我有一个类Animate,Animate a=newanimate(panel1,startingX,startingY,newX,newY);实例化将在起始位置创建一个节点,并每隔100毫秒单击一个按钮将其移动到所需的新位置。类节点的定义如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
class Node:Label
{
public Node(int x, int y)
{
this.Top = y;
this.Left = x;
}
public void updatePos(int x, int y)
{
this.Top += y;
this.Left += x;
}
}
}
这是动画类的定义:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Animate a = new Animate(panel1,0,0,1,1); //this is the actual instatiation test
Animate b = new Animate(panel1, 100, 0,2,2); //for node b
}
public class Animate
{
private Node l;
Thread th;
private delegate void cl(int x, int y);
Delegate del;
private int a, b;
public Animate(Panel p, int x, int y, int a, int b)
{
l = new Node(0,0);
del = new cl(l.updatePos);
this.a = a;
this.b = b;
this.l.AutoSize = true;
this.l.Location = new System.Drawing.Point(x, y);
this.l.Name = "label1";
this.l.Size = new System.Drawing.Size(35, 13);
this.l.TabIndex = 0;
this.l.Text = "label1";
p.Controls.Add(l);
th = new Thread(thread);
th.Start();
}
private void thread()
{
while (true)
{
try
{
l.Invoke(del, a, b);
Thread.Sleep(100);
}
catch (Exception e)
{
return;
}
}
}
}
}
}
有些人可能想知道我需要这个做什么,我正试图实现一个二进制搜索树和AVL模拟器,只使用纯C#编码的winform应用程序,这就是为什么我把标签称为“节点”当您搜索收到的异常消息的确切文本时,您发现了什么?您是否尝试合并您发现的任何建议?您这样做时发生了什么?我编辑了您的标题。请参阅“”,其中一致意见是“不,他们不应该”。另一个线程可以修改GUI元素:你是指我以前使用过的线程吗?我从谷歌找到了一个解决方案,但很难理解,有些人说最好使用backgroundworker来解决这类问题。使用线程时必须非常小心,因为正如他们所说的那样,它有风险,而且容易出现复杂错误。一个简单的解决方案可以将两个标签放在一个面板中,而不是移动标签,移动面板