Reputation: 1399
I use a loading circle component when I want to read some data from RSS. I want to display this circle component to user for waiting.
here is my code:
private void btnUpdateRSS_Click(object sender, EventArgs e)
{
if (txtRSSGroup_Address.Text.Trim() == string.Empty)
return;
DialogResult dr = MsgBox.Show("اطلاعات قبلی از این RSS حذف شده و با اطلاعات جدید جایگزین می شود. \n \n آیا مطمئن به انجام عملیات به روز رسانی هستید؟", "هشدار", Mode.YesNo);
if (dr == System.Windows.Forms.DialogResult.Yes)
{
try
{
string[] RSSNews;
loadingCircleFF.Visible = true;
string address = txtRSSGroup_Address.Text.Trim();
System.Threading.ThreadPool.QueueUserWorkItem((o) =>
{
RSSNews = Utility.RSSNews_Read(address);
for (int i = 0; i < RSSNews.Length; i++)
{
if (RSSNews[i] != null && RSSNews[i] != string.Empty)
{
RSS.RSSGroup_ID = RSSGroupID;
RSS.RSS_Content = RSSNews[i];
RSS.RSS_PersianDate = FreeControls.PersianDate.Now.ToString("YYYY/MM/dd");
RSS.User_FirstName = GlobalVariable.User_FirstName;
RSS.User_LastName = GlobalVariable.User_LastName;
RSS.Insert();
}
else
break;
}
this.BeginInvoke(new Action(() => { loadingCircleFF.Visible = false; }));
});
RSS.DeleteByGroup(RSSGroupID);
MsgBox.Show("عملیات به روز رسانی با موفقیت انجام شد.", "موفقیت", Mode.Information);
DTcancel_RSS(null, null);
}
catch
{
MsgBox.Show("خطا در دریافت اطلاعات از RSS", "خطا", Mode.Information);
}
}
}
but the problem is this:
before to display loading circle, it start to read from RSS and my application will be lock! so the loading circle never display.
how to fix this problem?
Upvotes: 3
Views: 256
Reputation: 12993
The problem is your UI won't get a chance to repaint itself after you set loadingCircleFF.Visible = true;
, after queuing a work item to the worker thread, your UI thread is busy handling RSS.DeleteByGroup(RSSGroupID);
and DTcancel_RSS(null, null);
, so it will not display immediately.
In my updated code, I placed them inside the body of QueueUserWorkItem, so they will not block your UI thread.
Noted that the work item is run on a worker thread so your app is not freezed. And when you hide loadingCircleFF after the RSSNews is successully read, you have to use BeginInvoke to marshal the call to the UI thread, since you can't access loadingCircleFF from a worker thread;
try
{
string[] RSSNews;
loadingCircleFF.Visible = true;
string address = txtRSSGroup_Address.Text.Trim();
System.Threading.ThreadPool.QueueUserWorkItem((o) =>
{
RSSNews = Utility.RSSNews_Read(address);
for (int i = 0; i < RSSNews.Length; i++)
{
if (RSSNews[i] != null && RSSNews[i] != string.Empty)
{
RSS.RSSGroup_ID = RSSGroupID;
RSS.RSS_Content = RSSNews[i];
RSS.RSS_PersianDate = FreeControls.PersianDate.Now.ToString("YYYY/MM/dd");
RSS.User_FirstName = GlobalVariable.User_FirstName;
RSS.User_LastName = GlobalVariable.User_LastName;
RSS.Insert();
}
else
break;
}
this.BeginInvoke(new Action(() => {
loadingCircleFF.Visible = false;
//MessageBox.Show("عملیات به روز رسانی با موفقیت انجام شد.", "موفقیت");
RSS.DeleteByGroup(RSSGroupID);
//MessageBox.Show("عملیات به روز رسانی با موفقیت انجام شد.", "موفقیت");
DTcancel_RSS(null, null);
}));
//If these methods don't access UI, call them normally, else wrap them with BeginInvoke.
//RSS.DeleteByGroup(RSSGroupID);
//DTcancel_RSS(null, null);
});
}
catch
{
MessageBox.Show("خطا در دریافت اطلاعات از RSS", "خطا");
}
Upvotes: 1