2011-12-21 34 views
3

我注意到,随着我的应用程序数据库的增长,返回结果所花的时间也增加了。在开始时这是微不足道的,因为返回数据源的时间很少。是否有可能为后台工作人员提供一种通用方法?

现在我处于临时让UI停止响应几秒的时间点,但我想创建background workers来完成这些任务。

创建这些的问题是,有大约9个按钮需要后台工作人员,他们所做的只是在DLL中调用不同的方法。有没有办法使用通用方法为后台工作人员使用API​​创建这些后台工作人员,还是应该创建与每个按钮相对应的Enum,并且是构造后台工作人员的方法所采用的参数。因此,我可以使用简单的switch来执行我选择的DLL中的任何方法?

示例代码:

void bg_DoWorkImports(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 

     try 
     { 
      e.Result = EngineBllUtility.GetNotImportedFiles(connectionString); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 

    void bg_RunWorkerCompletedImports(object sender, RunWorkerCompletedEventArgs e) 
    { 
     DataSet temp = (DataSet)e.Result; 
     if (e.Result != null) 
     { 
      importFileGridView.DataSource = temp.Tables[0]; 
     } 
    } 
+0

你使用的是.NET 4吗?对于这种类型的场景,TPL是BackgroundWorker的一个很好的替代方案... – 2011-12-21 18:44:24

+0

不幸的是,.NET 3.5 – ediblecode 2011-12-21 18:45:22

+0

将对Rx框架进行依赖是一个选择,因为它会让你获得TPL吗? http://msdn.microsoft.com/en-us/data/gg577610 – 2011-12-21 18:46:56

回答

2

您可以将Func<T>传递给创建BackgroundWorker并将该操作从内部调用到DoWork事件的方法。

像这样的事情

public class BackgroundWrapper<T> 
{ 
    private Func<T> workMethod; 
    private Action<T> completeMethod; 
    public static void StartBackgroundworker(Func<T> workMethod, Action<T> completeMethod) 
    { 
     BackgroundWrapper<T> bWrap = new BackgroundWrapper<T>(); 
     bWrap.workMethod = workMethod; 
     bWrap.completeMethod = completeMethod; 
     bWrap.Start(); 
    } 

    private void Start() 
    { 
     BackgroundWorker bw = new BackgroundWorker(); 
     bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
     bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 
     bw.RunWorkerAsync(); 
    } 

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     completeMethod((T)e.Result); 
    } 

    void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     e.Result = workMethod(); 
    } 
} 
+0

谢谢阿尔宾,我会探讨这种方法。 – ediblecode 2011-12-21 18:27:20

+2

你基本上重新创建了'System.Threading.Tasks'命名空间中的功能。使用正确的工具进行工作; 'BackgroundWorker'可能不是这里的正确工具。 – 2011-12-21 18:33:17

+1

@AdamRobinson这基本上就是我的想法 - 如果你要通过这个,你可以使用TPL,这在很多方面都更好用...... – 2011-12-21 18:44:05

0

我认为你需要建立某种形式的队列机制,其中一个背景工人拿起每一个点击按钮的工作和其他后揭开序幕之一。

+0

库马尔,这将是一个不受欢迎的功能 – ediblecode 2011-12-21 18:20:58

1

当然,我不明白为什么你不能创建一个“交换机”类的功能。事实上,你可能想这样做,因为它会使事情变得更加模块化并促进代码重用。

就enums而言,个人而言,我创建了类来传递大量的参数。

2

而不是使用的BackgroundWorker的,另一种是使用第三方物流。这会让你直接在每个成员内编写代码:

void buttonImport_Click(object sender, DoWorkEventArgs e) 
{ 
    Task.Factory 
     .StartNew(() => return EngineBllUtility.GetNotImportedFiles(connectionString)) 
     .ContinueWith(t => 
    {   
     try 
     { 
      if (t.Result != null) 
      { 
       importFileGridView.DataSource = t.Result.Tables[0]; 
      } 
     } 
     catch (AggregateException ex) 
     { 
      MessageBox.Show(ex.InnerException.Message); 
     } 
    }, TaskScheduler.FromCurrentSynchronizationContext()); 
} 
相关问题