2017-06-08 27 views
1

我是C#和麪向對象編程的新手。我有一個解析文本文件的應用程序。C# - 代表和BackgroundWorkers

默認情況下,程序在主線程上執行,因此應用程序凍結直至執行。

我有5個空白方法,它們以string作爲參數列表。

基於各種CheckBox選項,這5個void方法在組合中執行。

BackgroundWorker在不同的線程上執行操作。因此,應用程序不會凍結。

但是,我需要15+ BackgroundWorkers爲每個組合。

下面是我的代碼:

public partial class Form1 : Form 
{ 
    List<string> textFiles = new List<string>(); 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    public void mParsing(List<string> textFiles) { /* parsing logic */ } 
    public void iParsing(List<string> textFiles) { /* parsing logic */ } 
    public void aParsing(List<string> textFiles) { /* parsing logic */ } 
    public void qParsing(List<string> textFiles) { /* parsing logic */ } 

    public void Summary() 
    { 
     // Logic to generate summary 
    } 

    private void btnGo_Click(object sender, EventArgs e) 
    { 
     if (checkM.Checked == true && checkI.Checked == false && checkA.Checked == false && checkQ.Checked == false) 
     { 
      backgroundWorker1.RunWorkerAsync(); 
     } 
     else if (checkM.Checked == true && checkI.Checked == true && checkA.Checked == false && checkQ.Checked == false) 
     { 
      backgroundWorker2.RunWorkerAsync(); 
     }    

     //So On.... 
    } 

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     mParsing(textFiles); 
     Summary(); 
    } 
    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     DialogResult dialogResult = MessageBox.Show("View Summary?", MessageBoxButtons.YesNo); 
     if (dialogResult == DialogResult.Yes) 
     { 
      string summary = filepath; 
      Process.Start("notepad.exe", summary); 
     } 
    } 
    private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e) 
    { 
     mParsing(textFiles); 
     iParsing(textFiles); 
     Summary(); 
    } 
    private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     DialogResult dialogResult = MessageBox.Show("View Summary?", MessageBoxButtons.YesNo); 
     if (dialogResult == DialogResult.Yes) 
     { 
      string summary = filepath; 
      Process.Start("notepad.exe", summary); 
     } 
    } 
} 

Func<>不接受無效的數據類型,我有一個壞的時間瞭解代表和多線程技術。

我的問題是,我不知道如何避免多個後臺工作人員。這可以在代表的幫助下實施嗎?

更新: .NET Framework版本:4.0

+2

您是否在使用backgroundworker,因爲這是您發現多線程的第一種方式,而且您堅持使用它嗎?或者出於某些特定原因?我問,因爲它有點過時的方式來處理線程。正如你發現它過於複雜。 – Jamiec

+0

@Jamiec,我使用了後臺工作者,因爲我在過去使用過VB.NET應用程序。上述方法需要按順序運行。這怎麼能實現?另外,解釋將不勝感激。 – Tango

+0

RunWorkerAsync()允許您將參數傳遞給DoWork。顯然你會在這裏有很好的用處,一個BGW就足夠了。 –

回答

1

Coolerfarmer的答案與.NET 4.5效果很好。

然而,由於.NET 4.0的限制,設法實現異步執行與線程的幫助&代表

它可能不是表演相結合的方法執行的有效方式。

我所做的就是,創造了執行順序的個體的方法,並用下面的代碼:

public partial class Form1 : Form 
{ 
    List<string> textFiles = new List<string>(); 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    public void mParsing(List<string> textFiles) { /* parsing logic */ } 
    public void iParsing(List<string> textFiles) { /* parsing logic */ } 
    public void aParsing(List<string> textFiles) { /* parsing logic */ } 
    public void qParsing(List<string> textFiles) { /* parsing logic */ } 

    public void Summary() 
    { 
     // Logic to generate summary 
    } 

    private void btnGo_Click(object sender, EventArgs e) 
    { 
     if (checkM.Checked == true && checkI.Checked == false && checkA.Checked == false && checkQ.Checked == false) 
     { 
      Thread worker = new Thread(mOption); 
       if (!worker.IsAlive) 
       { 

        worker.Start(); 
        frm.Show(); // Displaying Form - Performing Operation.. Please Wait... 
        btn1.Enabled = false; 
       } 
     } 
     else if (checkM.Checked == true && checkI.Checked == true && checkA.Checked == false && checkQ.Checked == false) 
     { 
      Thread worker = new Thread(miOption); 
       if (!worker.IsAlive) 
       { 

        worker.Start(); 
        frm.Show(); // Displaying Form - Performing Operation.. Please Wait... 
        btn1.Enabled = false; 
       } 
     }    

     //So On.... 
    } 


     private void mOption() 
     { 
      mParsing(textFiles); 
      Summary(); 

      MethodInvoker inv = delegate 
      { 
       frm.Hide(); 

     DialogResult dialogResult = MessageBox.Show("View Summary?", MessageBoxButtons.YesNo); 
     if (dialogResult == DialogResult.Yes) 
     { 
      string summary = filepath; 
      Process.Start("notepad.exe", summary); 
     } 
       this.btn1.Enabled = true; 

      }; 
      this.Invoke(inv); 
     } 

     private void miOption() 
     { 
      mParsing(textFiles); 
      iParsing(textFiles); 
      Summary(); 

      MethodInvoker inv = delegate 
      { 
       frm.Hide(); 

     DialogResult dialogResult = MessageBox.Show("View Summary?", MessageBoxButtons.YesNo); 
     if (dialogResult == DialogResult.Yes) 
     { 
      string summary = filepath; 
      Process.Start("notepad.exe", summary); 
     } 
       this.btn1.Enabled = true; 

      }; 
      this.Invoke(inv); 
     } 

} 

與解釋的任何輸入是最歡迎,並感謝大家的投入和建議。

1

在C#中有異步/ AWAIT而這正是你所需要的。 拿這個例子:

private async void btnGo_Click(object sender, EventArgs e) 
{ 
    if (checkM.Checked == true && checkI.Checked == false && checkA.Checked == false && checkQ.Checked == false) 
    { 
     await mParsing(textFiles); 
     DialogResult dialogResult = MessageBox.Show("View Summary?", MessageBoxButtons.YesNo); 
     if (dialogResult == DialogResult.Yes) 
     { 
      string summary = filepath; 
      Process.Start("notepad.exe", summary); 
     } 
    } 
} 

對於這項工作這兩種功能,btnGo_ClickmParsing必須對自己的定義關鍵字異步。另外,解析函數的返回類型必須更改爲Task。

public async Task mParsing(List<string> textFiles) 
{ 
    //Method containing parsing logic 
} 

此外,您需要對您的(現在是異步)mParsing函數進行一些更改。 例如像new WebClient().DownloadString(url)阻塞調用必須與非阻塞更換調用new WebClient().DownloadStringTaskAsync(url)

一如往常有沒有可用的非阻塞調用你也可以使用Task.Run()

public async Task mParsing(List<string> textFiles) 
{ 
    await Task.Run(() => { 
     //Do blocking calls 
    }); 
} 
+0

Hello Coolerfarmer, 不幸的是,我正在使用.NET Framework 4.我無法將其更改爲最新版本。如何在沒有異步的情況下實現? – Tango