Elahe
Elahe

Reputation: 1399

How to display Processing component in windows form

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

Answers (1)

kennyzx
kennyzx

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

Related Questions