C# ProgressBar Threading mobile 6

人盡茶涼 提交于 2019-12-12 05:13:33

问题


I am programming an application for downloading articles from an SQL Database on the internet. I have programmed the Website for managing the articles. Now I'm downloading the article List in gzip Format and then I decompress them to a xml-File. When I'm done I want to insert the articles to the mobile phone. This works great. Now I want to add an progress Bar to see the state of the insertion. I tried with Threading but this doesn't work. I'm posting some pieces of code from my application and also the progressUpdate methods.

private void btn_send_Click(object sender, EventArgs e)
    {
        label1.Text = "Download started";
        string ArticlesURL = "URLTOSITE";
        InvokeAsync(ArticlesURL);

    }

private void InvokeAsync(string URL)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.AllowWriteStreamBuffering = true;
        allDone.Reset();
        request.BeginGetRequestStream(new AsyncCallback(ReadArticlesCallback), request);
        allDone.WaitOne();
        request.BeginGetResponse(new AsyncCallback(ResponseArticlesCallback), request);
    }

private static void ReadArticlesCallback(IAsyncResult asynchronousResult)
    {
        HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
        //End the operation.
        Stream postSream = request.EndGetRequestStream(asynchronousResult);

        string postData = "articles=test";
        //Convert the string into a byte array.
        byte[] byteArray = Encoding.UTF8.GetBytes(postData);
        //Write to the request stream.
        postSream.Write(byteArray, 0, postData.Length);
        postSream.Close();
        allDone.Set();
    }

    private static void ResponseArticlesCallback(IAsyncResult asynchronousResult)
    {
        Form1 f = new Form1();
        HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
        HttpWebResponse resp = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
        Stream streamResponse = resp.GetResponseStream();
        StreamReader streamRead = new StreamReader(streamResponse);
        string responseString = streamRead.ReadToEnd();
        nbrArticles = Convert.ToInt16(responseString);
        // Close the stream object.
        streamResponse.Close();
        streamRead.Close();
        // Release the HttpWebResponse.
        resp.Close();
        f.truncate_articles();
        f.get_articles();
    }

private void get_articles()
    {
        string url = "URLTOSITE";
        int startPoint = 0;
        DownloadZipFile((object)startPoint, url);
        DecompressFile();
        getXmlAndInsertInDB();
    }
private void getXmlAndInsertInDB()
    {
        int total = nbrArticles;
        int count = total / 100; //How much articles are 1 percent
        int i = 0;
        String barcode = "";
        String name = "";
        bool state = false;
        XmlTextReader reader = new XmlTextReader("Program Files\\SmartDeviceProject1\\articles.xml");
        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element: //The node is an element
                    while (reader.MoveToNextAttribute()) //Get the attributes like barcode, lastname, firstname, pincode
                        switch (reader.Name)
                        {
                            case "barcode":
                                barcode = reader.Value.ToString();
                                state = false;
                                break;
                            case "name":
                                name = reader.Value.ToString();
                                state = true;
                                break;
                        }
                    break;
            }
            if (state == true)
            {
                cmd.CommandText = "INSERT INTO articles(barcode, name) " +
                    "VALUES('" + barcode + "','" + name + "');";
                cmd.ExecuteNonQuery();
                state = false;
                i++;
                if (i == count)
                {
                    Thread t = new Thread(new ThreadStart(this.incrementProgressBar));
                    t.Start();
                    //incrementProgressBar();
                    i = 0;
                }
            }
        }
        reader.Close();
    }

    private void updateProgressBarMethod(int progress)
    {
        if (progressBar1.InvokeRequired)
        {
            //It was called from a non UI thread so we create a delegate
            //and have the UI Thread call this method again
            UpdateProgressBar = new UpdateProgressBarDelegate(updateProgressBarMethod);
            this.Invoke(UpdateProgressBar, progress);
        }
        else
        {
            //Called from the UI Thread OK to update
            //update your progress bar here
            progressBar1.Value += progress;
        }
    }

    private void incrementProgressBar()
    {
        //Call the method to update progress Bar on UI thread
        //we do not need a delegate here that will be taken care of
        //in the method
        updateProgressBarMethod(1);
        Application.DoEvents();
    }

I think the problem is that I am using Callbacks. I have read that the Callbacks are also starting Threads. So I think the problem is there but I can't solve it.


I've found another very good site for threading with mobile applications: Updating the User Interface from a Worker Thread

Now with the new code, the debugger stops always at the same piece of code without any notification or exception :( Here is my new code:

                if (i == count)
                {
                    this.info_percent = "Synchro " + step.ToString() + "%";
                    this.Invoke(new EventHandler(WorkerUpdate)); //The Debugger stops here!
                    i = 0;
                    step++;
                    Thread.Sleep(700);
                }

    public void WorkerUpdate(object sender, EventArgs e)
    {
        this.lbl_percent.Text = this.info_percent;
        this.lbl_percent.Update();
        this.progressBar1.Value = step;
        this.progressBar1.Update();
    }

The Debugger stops at: this.Invoke(new EventHandler(WorkerUpdate));


回答1:


I would suggest using the Background worker class. I had a similar problem and implemented the Background worker and it fixed my problem. Hopefully it will fix yours also

http://www.dotnetperls.com/backgroundworker

http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

I found another thread discussing this and thought it would help:

Is there a BackgroundWorker replacement for .NET Compact Framework 3.5?




回答2:


Your code will always hang at this point:

if (i == count)
{
  this.info_percent = "Synchro " + step.ToString() + "%";
  this.Invoke(new EventHandler(WorkerUpdate)); //The Debugger stops here!
  i = 0;
  step++;
  Thread.Sleep(700);
}

Make these changes:

public delegate void MethodInvoker(); // this is not defined in CF

if (i == count)
{
  this.info_percent = "Synchro " + step.ToString() + "%";
  object sender = null; // make this whatever you want/need
  EventArgs e = new EventArgs();
  if (this.InvokeRequired) {
    MethodInvoker mi = delegate { WorkerUpdate(sender, e); } };
    this.BeginInvoke(mi);
  } else {
    WorkerUpdate(sender, e);
  }
  i = 0;
  step++;
  // Thread.Sleep(700); Why is this here?
}

This should prevent those obnoxious freezes.



来源:https://stackoverflow.com/questions/8309193/c-sharp-progressbar-threading-mobile-6

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!