开发者

When using Parallel BeginInvoke is working while Invoke is not - c# 4.0

When i use invoke inside AddListBoxItem function as seen below software become unreponsive and frozen but if i use BeginInvoke it works. Why is that happening ?

visual studio 2010 , C# 4.0

 private void button2_Click(object sender, EventArgs e)
{
    var watch = Stopwatch.StartNew();
    Parallel.For(2, 20, (i) =>
    {
        var result = SumRootN(i);
        AddListBoxItem("root " + i + " : " + result);
    });
    AddListBoxItem(watch.ElapsedMilliseconds.ToString());            
}

private delegate void AddListBoxItemDelegate(object item);

private void AddListBoxItem(object item)
{
    if (this.listBox1.InvokeRequired)
    {
        this.listBox1.Invoke(new AddListBoxItemDelegate(this.AddListBoxItem), item);
    }
    else
    {
        th开发者_如何学Pythonis.listBox1.Items.Add(item);
    }
}


Your UI thread will wait for Parallel.For to complete before it continues. That means it can't process any further UI messages until it's completed.

Now when the worker threads call Invoke, they wait until the UI thread processes the delegate before they continue. So they're waiting for the UI thread to get free, basically.

Hence, you have a deadlock - the UI thread is waiting for the tasks, which are waiting for the UI thread... BeginInvoke works because then the task threads don't wait for the delegates to be processed in the UI thread.

I would suggest that you don't call Parallel.For in the UI thread to start with. You'll block the UI until it completes anyway, which isn't a good idea. Do the whole thing in a background thread - then you can still use Invoke if you want, and while it's doing the computation the UI will still be responsive.


It sounds like you are deadlocking the UI thread. This makes perfect sense, as your button2_Click doesn't exit until For completes, and in particular, no message-loop events can be processed until button2_Click has completed. If you are on a different thread, Invoke uses a message-loop event, and does not return until that item is processed - so nothing will ever be done - and For / button2_Click will never complete.

By using BeginInvoke you simply queue this work - BeginInvoke returns immediately. This means that the For can complete, which lets button2_Click complete, which then allows the message-loop events to be processed (updating the UI).


I think it's because auf the Mainthread beeing blocked in the above Click event, waiting to finish AddListBoxItem, which is waiting the buttion2_click event to return.
You shouldn't have Controller logic in your UI, so the main problem that the Click isn't calling back a logic in a different thread.

After Implementing an thread for your logic, your GUI wouldn't block and would refresh easy in any situation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜