0

我正在编写一个应用程序,用于从 Internet 上的 SQL 数据库下载文章。我已经对网站进行了编程以管理文章。现在我正在下载 gzip 格式的文章列表,然后将它们解压缩为 xml 文件。完成后,我想将文章插入手机。这很好用。现在我想添加一个进度条来查看插入的状态。我尝试使用线程,但这不起作用。我正在发布我的应用程序中的一些代码以及progressUpdate 方法。

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();
    }

我认为问题在于我正在使用回调。我读过回调也在启动线程。所以我认为问题就在那里,但我无法解决。


我找到了另一个非常好的使用移动应用程序线程的站点:从工作线程更新用户界面

现在有了新代码,调试器总是在同一段代码处停止,没有任何通知或异常:(这是我的新代码:

                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();
    }

调试器停在: this.Invoke(new EventHandler(WorkerUpdate));

4

2 回答 2

0

我建议使用后台工作人员类。我遇到了类似的问题并实施了后台工作人员,它解决了我的问题。希望它也能解决你的问题

http://www.dotnetperls.com/backgroundworker

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

我找到了另一个讨论这个问题的线程,并认为它会有所帮助:

.NET Compact Framework 3.5 是否有 BackgroundWorker 替代品?

于 2011-12-06T16:26:19.377 回答
0

此时您的代码将始终挂起:

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 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?
}

这应该可以防止那些令人讨厌的冻结。

于 2012-07-19T16:46:34.777 回答