2016-11-08 50 views
0

我開發了一個GUI winforms來讀取和解碼CSV文件並將其保存爲Excel和CSV格式。我在datagridview中顯示解碼的數據。一切工作正常,但出於一些令人害怕的原因圖形用戶界面凍結,因爲大文件或可能是天氣寒冷。它仍然做它想要做的事情,但顯示(軟件沒有響應)。我也使用了線程和後臺工作,但仍然沒有希望。這裏是代碼。請分享任何幫助嘗試讀取和解碼大文件時C#GUI凍結

public delegate void UpdatingTable(); 
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     Invoke(new UpdatingTable(DecodingData)); 
    } 


    private void cnvrtB_Click(object sender, EventArgs e) 
    { 
     progressBar1.Enabled = true; 
     progressBar1.Visible = true; 
     saveB.Visible = true; 
     cnvrtB.Enabled = false; 
     label5.Visible = true; 
     backgroundWorker1.RunWorkerAsync(); 
     //DecodingThread = new Thread(new ThreadStart(StartDecoding)); 
     //DecodingThread.IsBackground = true; 

     //if (!(DecodingThread.IsAlive) || DecodingThread == null) 
     //{ 
     // progressBar1.Enabled = true; 
     // progressBar1.Visible = true; 
     // saveB.Visible = true; 
     // cnvrtB.Enabled = false; 
     // label5.Visible = true; 
     // Thread.Sleep(2000); 
     // DecodingThread.Start(); 
     //} 
     //else if (DecodingThread.IsAlive) 
     //{ 
     // progressBar1.Enabled = true; 
     // progressBar1.Visible = true; 
     // saveB.Visible = true; 
     // cnvrtB.Enabled = false; 
     // label5.Visible = true; 
     // DecodingThread.Resume(); 
     //}   

    } 


    private void StartDecoding() 
    { 
     Thread.Sleep(1000); 
     Invoke(new UpdatingTable(DecodingData)); 
    } 
    public void DecodingData() 
    { 
     try 
     { 
      //delete old records     
      records.Clear(); 

      //get records from converter 
      if (VersionNumber == 1) 
      { 
       records.AddRange(LogEventDecode.getRecords()); 

      } 
      else if (VersionNumber == 0) 
      { 
       records.AddRange(LogEventDecode.getRecordsOld()); 
      } 

      //create datatable for records 
      table = new System.Data.DataTable("data"); 
      //create columns 
      table.Columns.Add("Time", typeof(System.DateTime)); 
      table.Columns.Add("Date", typeof(System.DateTime)); 
      table.Columns.Add("dt", typeof(System.DateTime)); 
      table.Columns.Add("User", typeof(System.String)); 
      table.Columns.Add("SourceInformation", typeof(System.String)); 
      table.Columns.Add("SourceType", typeof(System.String)); 
      table.Columns.Add("SourceCondition", typeof(System.String)); 
      table.Columns.Add("securityLevel", typeof(System.String)); 
      table.Columns.Add("AdditionalInformation", typeof(System.String)); 
      table.Columns.Add("RubCondition", typeof(System.String)); 

      //populate datatable 
      foreach (LogRecord r in records) 
      { 
       DataRow row = table.NewRow(); 
       row["Time"] = r.Time; 
       row["Date"] = r.Date; 
       row["dt"] = r.dt; 
       row["User"] = r.User; 
       row["SourceInformation"] = r.SourceInformation; 
       row["SourceType"] = r.SourceType; 
       row["SourceCondition"] = r.SourceCondition; 
       row["securityLevel"] = r.SecurityLevel; 
       row["AdditionalInformation"] = r.AdditionalInformation; 
       row["RubCondition"] = r.RubCondition; 
       table.Rows.Add(row); 
       //DecodingCount++; 
       //label5.Text = "Decoded" + DecodingCount + " out of Total Logs " + records.Count; 
      } 
      view = new DataView(table); 

      //bind to grid     

      //DecodingThread.Abort(); 
     } 
     catch 
     { 
      MessageB.Show("Please make sure you have Imported the File \nOR\n The imported file is not corrupted.", "File Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      cnvrtB.Enabled = true; 
     } 

    } 

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     logRecordBindingSource.DataSource = view; 


     cnvrtB.Enabled = true; 

     progressBar1.Visible = false; 
     progressBar1.Enabled = false; 
     label5.Visible = false; 
    } 

給定的例子同時顯示線程和後臺方法

感謝

+0

你從哪裏打電話StartDecoding?它有睡眠,如果從UI線程調用將會凍結UI –

+0

爲什麼我在後臺工作者中調用'Invoke'? – KMoussa

+0

調用調用來更新表 –

回答

2

不要叫Invoke在後臺工作,按照MSDN,這裏是Invoke做:

在擁有控件底層窗口句柄的線程上執行委託。

所以你的背景工人正在執行的控制的(即GUI)線程代碼

+0

感謝您的回答,但我怎樣才能使用委託,以及它如何防止GUI凍結..請回答這個愚蠢的問題 –

+0

不知道我明白你的問題 - 你可以調用'DecodeingData'在'backgroundWorker1_DoWork'中,然後處理後臺工作人員的'RunWorkerCompleted'事件,以便在完成閱讀後更新GUI ..是否回答你的問題? – KMoussa

+0

謝謝,這就是我的想法。希望它會起作用。謝謝@KMoussa –