Hi,
I came across a code which was using BeginInvoke to update label text in a certain way, which I found strange and I can't understand why would somebody do that.
If I want to use threading to allow good user experience, I would create a thread and update the labels in the new thread using Thread.Start nethod. Why would I use the below approach?
If you guys can tell me what is the benefit, if any, of using this particular approach, that would be great.
public delegate void loadCustomersDelegate();
private delegate void updateLabelDelegate(Label lb, string text);
public void updateLabel(Label lb, string text)
{
lb.Text = text;
}
public void loadCustomerDetails()
{
loadCustomersDelegate del = new loadCustomersDelegate(loadCustomerDetailsAction);
IAsyncResult res = del.BeginInvoke(null, null);
while (!res.IsCompleted)
{
}
}
public void loadCustomerDetailsAction()
{
BeginInvoke(new updateLabelDelegate(updateLabel), new object[] { lblCustomerName, resp.AddressItems[0].ADName.ToString() });
BeginInvoke(new updateLabelDelegate(updateLabel), new object[] { lblAddress1, resp.AddressItems[0].AD1.ToString() });
BeginInvoke(new updateLabelDelegate(updateLabel), new object[] { lblAddress2, resp.AddressItems[0].AD2.ToString() });
BeginInvoke(new updateLabelDelegate(updateLabel), new object[] { lblAddress3, resp.AddressItems[0].AD3.ToString() });
BeginInvoke(new updateLabelDelegate(updateLabel), new object[] { lblAddress4, resp.AddressItems[0].ADCode.ToString() });
BeginInvoke(new updateLabelDelegate(updateLabel), new object[] { lblPCode, resp.AddressItems[0].PCode.ToString() });
BeginInvoke(new updateLabelDelegate(updateLabel), new object[] { lblTelephone, resp.AddressItems[0].Tele.ToString() });
BeginInvoke(new updateLabelDelegate(updateLabel), new object[] { lblFax, resp.AddressItems[0].Fax.ToString() });
BeginInvoke(new updateLabelDelegate(updateLabel), new object[] { lblSLCode, resp.AddressItems[0].SLCode.ToString() });
BeginInvoke(new updateLabelDelegate(updateLabel), new object[] { lblSLBalance, "£" + resp.AddressItems[0].SLBalance.ToString() });
BeginInvoke(new updateLabelDelegate(updateLabel), new object[] { lblSLMonthsOld, resp.AddressItems[0].SLMonthsOld.ToString() });
BeginInvoke(new updateLabelDelegate(updateLabel), new object[] { lblSLCreditRating, "£" + resp.AddressItems[0].SLCreditRating.ToString() });
}
Update
I wrote an application to compare this approach with other ways. While running the application in debug mode I got the error "Invoke or BeginInvoke cannot be called on a control until the window handle has been created." on the first BeginInvoke in method UpdateCustDetails. Although, it doesn't give any runtime error while running the code without debug. Any ideas??
Below is my code:-
public delegate void UpdateLabelDelegate(Label lb, string text);
public delegate void loadCustomersDelegate();
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
loadCustomersDelegate del = new loadCustomersDelegate(UpdateCustDetails);
IAsyncResult ar = del.BeginInvoke(null, null);
while (!ar.IsCompleted)
{
}
}
public void updateLabel(Label lb, string text)
{
lb.Text = text;
}
public void UpdateCustDetails()
{
BeginInvoke(new UpdateLabelDelegate(updateLabel), new object[] { label1, "Test" });
BeginInvoke(new UpdateLabelDelegate(updateLabel), new object[] { label2, "Test1234" });
BeginInvoke(new UpdateLabelDelegate(updateLabel), new object[] { label3, "Test5678" });
BeginInvoke(new UpdateLabelDelegate(updateLabel), new object[] { label4, "Test0000" });
}
}
Thanks, Abhi.