有一个面板我想添加k
控件。我想为每个控件指定任务以供以后使用。所以:
*更新以下其他一些代码;请观看第三个代码 *
*****Update*****
Child Control : PacketData (can be a Button)
Main Control : panel
PlaceData() changes the left and top randomly.
我这样做了:
Parallel.For(0, k, (m) =>
{
tasks[m] = Task.Factory.StartNew(() =>
{
PacketData data = new PacketData();
data.StartTime = sw.ElapsedMilliseconds;
lock (data_adding_lock)
{
IAsyncResult iar = panel1.BeginInvoke(new MethodInvoker(()=>{
PlaceData(ref data);
panel1.Controls.Add(data);
}));
panel1.EndInvoke(iar);
while (iar.IsCompleted ==false ) ;
}
});
});
它的工作原理有时很好,但有时却没有,例如有时它只向面板添加一个PacketData
控制 。我是否放弃了比赛条件?
我也试过这个,但没有工作......
Parallel.For(0, k, (m) =>
{
tasks[m] = Task.Factory.StartNew(() =>
{
PacketData data;
lock (data_instancing_lock) {
data = new PacketData();}
data.StartTime = sw.ElapsedMilliseconds;
IAsyncResult iar = panel1.BeginInvoke(new MethodInvoker(()=>{
PlaceData(ref data);
lock(data_adder_lock){
panel1.Controls.Add(data);}
}));
panel1.EndInvoke(iar);
//PlaceData(ref data);
});
});
的 的 * UPDATE * *
这是另一个例子(不起作用......)
object l1 = new object();
object l2 = new object();
private delegate void AdderDel(Button bb);
public Form1()
{
InitializeComponent();
}
private void AddControl(Button x)
{
lock (l2)
{
this.Controls.Add(x);
}
}
private void Place(ref Button btn)
{
Random rnd = new Random();
int x = rnd.Next(0, this.Width-100);
int y = rnd.Next(0, this.Height-100);
btn.Left = x;
btn.Top = y;
}
private void button1_Click(object sender, EventArgs e)
{
int n = 5;
Task[] t = new Task[n];
AdderDel ad = new AdderDel(AddControl);
Parallel.For(0, n, (k) =>
{
t[k] = Task.Factory.StartNew(() =>
{
Button b = new Button();
b.Text = k.ToString();
b.Height = 50;
Place(ref b);
this.BeginInvoke(ad, b);
});
});
}
为什么?
答案 0 :(得分:0)
您的代码对于它正在尝试的内容来说太复杂了,特别是因为我认为在这里使用并行性没有任何优势。 (虽然你的真实代码中可能有某些原因,但很难从你的样本中得知。)我认为你不应该使用并行性,直到你了解它是如何工作的。应该避免使用试错法进行编程,因为这意味着您实际上并不了解自己的代码,因此会导致错误。
但是代码中的实际问题与并行性没有任何关系。这是你错误地使用Random
。如果使用默认构造函数,则Random
将以当前时间播种。这意味着如果您像往常一样短时间创建多个Random
实例,它们将返回相同的数字序列。这意味着所有按钮都放在表单上,除了它们都在同一个地方,所以你只看到其中一个。
解决此问题的最简单方法是在一个字段中只有一个Random
实例,并且只能从UI线程访问它,或者在使用它时使用锁。
如果您的代码可以正常运行,您可以考虑将其发布到Code Review Stack Exchange以便对其进行审核,然后解释一下您实际尝试做什么。