2016-12-23 51 views
0

当我开发多个较小的应用程序时,我注意到我可以在这里或那里使用新的线程进行后台任务。我已经尝试了几个选项,主要是后台工作人员和代表。我想要做的是有一个专用的线程类来运行我的所有线程,我可以在多个程序中重用。创建一个类来处理线程

我正在寻找有关在这种情况下阅读或查看或应该做什么的指导。我现在该怎么失败

例子:

主线程(GUI)开始 用户点击按钮1,它通过一些逻辑进入和启动多个任务密集型计算(这将冻结GUI直到计算完成)。

我希望做的是看成是这样的..

主线程(GUI)开始 用户点击按钮1创建将在排队的某种 GUI线程的报告清单作为线程过程进度线程计算 线程在 (可能?)线程完成和出队稍后有线程类循环在后台等待项目排队和处理,因为它走了。

我的小任务,典型的方法是

Thread fooThread= new Thread((ThreadStart)delegate 
    { 
     //command 
    }); 

    fooThread.Start(); 

问题是,我的按钮事件有更多的项目在他们(也许我应该重构呢?)

样品

private void btnCopy_Click(object sender, EventArgs e) 
{ 
    //check file exists, check destination exists, etc 
    //start new thread 

    Thread fooThread= new Thread((ThreadStart)delegate 
    { 
     //copy files to destination using method foobarCopy(params) 
    }); 

    fooThread.Start(); 

//if file copy is successful, inform user on GUI. 
} 

我我主要使用.NET2.0,但根据需要可能会达到4.5。

+0

您按钮点击中的代码应该可能是您的班级。 'FileCopier'或任何带有'Start()'的。确定它是否已完成并且通知取决于您,但这真的是您的课程。我不确定你需要创建自己的线程管理器类,而是将该代码重构为业务对象,并且从那里你至少可以看到下一个重构的基类中可以做些什么。 – TyCobb

+2

听起来像使用现有的线程池支持会更好。 –

+0

也许您应该使用异步回调方法来处理gui的结果,或者您可以使用面向方面的框架检查或控制您的逻辑,数据等,如spring.net aop。 – FreeMan

回答

0

升级你的应用程序到.Net 4.5,你会放心。您将能够利用任务和任务并行库(TPL)基础结构和await异步构造。

在当今的.Net时代,你必须有真正令人信服的理由,你为什么要手动创建自己的线程,而不是利用现有的线程池。一个这样的原因可能是,如果你寻求它们在你的过程中得到新创建的线程的绝对控制被提到,但以下的原因不限于:

  • 当应该得到创建我的线程?
  • 应该在我的过程中创建多少个新线程?
  • 当我的线程应该被丢弃?
  • 从OS调度算法的立场来看,新线程的优先级应该是多少?例如高,中,低
  • 我的线程应该是后台线程还是前台线程?

对于典型的业务线应用程序,您几乎不需要对线程进行如此多的精细控制。

所以,任务是你最好的朋友,可以帮助你摆脱冻结的用户界面问题。你可以看我的博客here了解更多详情。以下是我将如何重写您的代码:

private async void btnCopy_Click(object sender, EventArgs e) 
{ 
    //check file exists, check destination exists, etc 
    string sourceFile = @"C:\a.txt", destinationFile = @"C:\b.txt"; 
    //Let TPL do the heavy lifting of interacting with disk for I/O 
    var copyTask = await CopyFile(sourceFile, destinationFile); 

    /* 
    //Manual thread instantiation not needed. Hence commented 
    Thread fooThread = new Thread((ThreadStart)delegate 
    { 
     //copy files to destination using method foobarCopy(params) 
    }); 

    fooThread.Start(); 
    */ 

    //if file copy is successful, inform user on GUI. 
    if (copyTask) 
    { 
     //show a message box 
    } 
} 

private async Task<bool> CopyFile(string sourceFile, string destinationFile) 
{ 
    bool fileCopiedSuccessfully = true; 
    //here use async I/O methods from stream class which support the notion of tasks 
    try 
    { 
     using (FileStream sourceStream = File.Open(sourceFile, FileMode.Open)) 
     { 
      using (FileStream destinationStream = File.Create(destinationFile)) 
      { 
       //exactly at this point of time when the actual copy happens your GUI thread is completely 
       //free to do anything. It won't freeze. 
       //This work happens on a thread-pool thread which you don't have to worry about. 
       await sourceStream.CopyToAsync(destinationStream); 
      } 
     } 
    } 
    catch (IOException ioex) 
    { 
     fileCopiedSuccessfully = false; 
     MessageBox.Show("An IOException occured during copy, " + ioex.Message); 
    } 
    catch (Exception ex) 
    { 
     fileCopiedSuccessfully = false; 
     MessageBox.Show("An Exception occured during copy, " + ex.Message); 
    } 
    return fileCopiedSuccessfully ; 
} 
相关问题