2011-11-29 87 views
0

我正在編寫一個應用程序,用於從互聯網上的SQL數據庫下載文章。我已經編制了管理文章的網站。現在我正在以gzip格式下載文章列表,然後將它們解壓縮爲一個xml-File。完成後,我想將文章插入手機。這很好。現在我想添加一個進度條來查看插入的狀態。我嘗試了線程,但這不起作用。我從我的應用程序發佈了一些代碼,還發布了progressUpdate方法。C#ProgressBar線程移動6

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

我認爲問題在於我正在使用回調。我已經讀過,回調也開始線程。所以我認爲問題在那裏,但我無法解決。


,我發現了另一個非常好的網站與移動應用程序線程:Updating the User Interface from a Worker Thread

用新的代碼

現在,調試器在同一段代碼總是停沒有任何通知或異常:(這裏是我的新代碼:

   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(新的EventHandler(WorkerUpdate));

回答

0

我建議USI後臺工作者類。我有一個類似的問題,並實施了後臺工作,它解決了我的問題。希望這將解決你也

http://www.dotnetperls.com/backgroundworker

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

我發現另一個線程討論這一點,並認爲這將有助於:

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

+0

感謝您的回答。但我已經讀過關於Backgroundworker和我的知識,有沒有這樣的Windows Mobile 6編程工具... –

+0

已更新的答案。 – mW00t

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

這應該避免那些討厭的凍結。