2014-01-14 42 views
-1

我有含有執行繁重的操作阻塞UI一個Run()方法的類。 我創建了類的幾個實例,我需要執行run()同步W/O阻塞UI。 我已成功地做到用一個BackgroundWorker但是我不喜歡,因爲這種解決方案「Application.DoEvents()」因爲如果我需要等待後臺工作完成,存在使用不使用BW。我應該使用同步操作。 任何想法我可以用呢?如何執行重同步操作W/O阻塞UI?

class MyClass 
{ 
    public void Run() 
    { 
     for (int i = 0; i < 1000; i++) 
     { 
      Console.WriteLine(i); 
     } 
    } 
} 


public partial class Form1 : Form 
{ 
    List<MyClass> lmc = new List<MyClass>(); 

    public Form1() 
    { 
     InitializeComponent(); 

     MyClass m1 = new MyClass(); 
     MyClass m2 = new MyClass(); 

     lmc.Add(m1); 
     lmc.Add(m2); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     foreach (MyClass item in lmc) 
     { 
      BackgroundWorker bw = new BackgroundWorker(); 
      bw.DoWork += bw_DoWork; 
      bw.WorkerSupportsCancellation = true; 
      bw.RunWorkerAsync(item); 
      while (bw.IsBusy) 
      { 
       Application.DoEvents(); 
      } 
     } 
    } 

    void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     ((MyClass)e.Argument).Run(); 
     ((BackgroundWorker)sender).CancelAsync(); 
    } 
} 
+1

所以,基本上,你想一個解決方案,是不是異步任務,儘管這正是異步任務的情況? –

+1

您使用的是.NET Framework 4.5嗎?如果是,請查看C#5中的新異步/等待關鍵字。 –

+0

這可能很有用http://msdn.microsoft.com/en-us/library/dd460717.aspx – Mike

回答

1

「DoEvents」確實不是一個好方法。 我建議使用TPL任務。

private void button1_Click(object sender, EventArgs e) 
{ 
    Task t = new Task(() => 
    { 
     lmc.ForEach(l => l.Run()); 
    }); 

    t.Start(); 

    t.ContinueWith(_ => 
    { 
     Invoke(new System.Action(UploadDone)); 
    }); 

} 

private void UploadDone() 
{ 
    Console.Write("Done"); 
} 

釋放UI的唯一方法是釋放主線程。你必須開始一個新的線程。

順便說一句,如果LMC任務不互相轉發,你也可以做Parallel Foreach

感謝,
阿米爾