2009-10-21 89 views
29

我有两个函数,我想在不同的线程上运行(因为它们是数据库的东西,而不是立即需要)。在新线程上运行简单函数的最佳方式?

的功能有:

  getTenantReciept_UnitTableAdapter1.Fill(rentalEaseDataSet1.GetTenantReciept_Unit); 
      getTenantReciept_TenantNameTableAdapter1.Fill(rentalEaseDataSet1.GetTenantReciept_TenantName); 

在JavaScript中,我知道我可以创建创建一个匿名函数和像这样的东西很容易把它在一个新的线程:

setTimeout(new function(){doSomethingImportantInBackground();}, 500); 

有在C#中这样的东西?

+2

就在旁边,但Javascript代码不会**在新线程上调用函数,它只是安排它在将来运行。 Javascript是单线程的,所以所有的代码都运行在同一个线程上。 – 2016-02-28 00:44:33

回答

66

你的问题不是很清楚,恐怕。你可以轻松地开始一个新的线程与一些代码,用在C#2匿名方法,和在C#3 lambda表达式:

匿名方法:

new Thread(delegate() { 
    getTenantReciept_UnitTableAdapter1.Fill(
     rentalEaseDataSet1.GetTenantReciept_Unit); 
}).Start(); 
new Thread(delegate() { 
    getTenantReciept_TenantNameTableAdapter1.Fill(
     rentalEaseDataSet1.GetTenantReciept_TenantName); 
}).Start(); 

Lambda表达式:

new Thread(() => 
    getTenantReciept_UnitTableAdapter1.Fill(
     rentalEaseDataSet1.GetTenantReciept_Unit) 
).Start(); 
new Thread(() => 
    getTenantReciept_TenantNameTableAdapter1.Fill(
     rentalEaseDataSet1.GetTenantReciept_TenantName) 
).Start(); 

你可以使用与Control.Invoke相同类型的语法,但它稍微复杂一些,因为可以使用任何委托 - 因此您需要告诉编译器您正在使用哪种类型,而不是依赖于隐式转换。这可能比较容易写:

EventHandler eh = delegate 
{ 
    // Code 
}; 
control.Invoke(eh); 

EventHandler eh = (sender, args) => 
{ 
    // Code 
}; 
control.Invoke(eh); 

作为一个侧面说明,是你的名字是那么长?你能缩短它们以获得更易读的代码吗?

+0

我认为OP希望每次调用Fill()以在其自己的线程上运行。但除此之外,发现。 – LBushkin 2009-10-21 20:10:53

+0

@Lushushkin:会调整。说实话,这不是一个非常明确的问题。 – 2009-10-21 20:13:40

+0

我打算扩大我的答案,包括拉姆达的,但你的是更完整(和更好)无论如何。背景工作组件仍然是一个选项,因为您不必担心Control.Invoke。 – RichardOD 2009-10-21 20:14:14

6

你可以使用匿名方法:


void Foo() 
{ 
    Thread myThread = new System.Threading.Thread(delegate(){ 
       //Your code here 
    }); 
    myThread.Start(); 
} 
+1

它给出错误跨线程操作无效:从其创建的线程以外的线程访问控制。 – 2014-08-05 07:18:27

+0

@PrakashVishwakarma这是因为您正在访问窗体的Control元素,但是在与UI线程不同的线程上。你需要做textboxInput.Invoke(new MethodInvoker(()=> {Whatever();}));它会安排匿名函数()=> {Whatever(); }在UI线程上。 – 2016-10-31 20:16:25

10

启动线程是比较昂贵的。

你可能会使用一个线程从线程池的更好:

ThreadPool.QueueUserWorkItem(unused => 
    getTenantReciept_UnitTableAdapter1.Fill(
     rentalEaseDataSet1.GetTenantReciept_Unit) 
); 
ThreadPool.QueueUserWorkItem(unused => 
    getTenantReciept_TenantNameTableAdapter1.Fill(
     rentalEaseDataSet1.GetTenantReciept_TenantName) 
); 
+0

您如何知道线程何时完成? 也就是说。我做了:'ThreadPool.QueueUserWorkItem(unused => data [0] = get_data(a,b));''ThreadPool.QueueUserWorkItem(unused => data [1] = get_data(a2,b2));' – 2016-09-29 15:27:53

+1

这是2016现在。 'ThreadPool.QueueUserWorkItem'是2009年。使用任务(请参阅@JSideris)的答案,或'异步'。两者都提供了等待任务完成并检索返回值的方法。 – oefe 2016-09-29 19:44:47

22

什么有人说类似的 - 我觉得任务是有点简单(支持如.net 4,可以作为如下使用.net 4.5):

Task mytask = Task.Run(() => 
{ 
    //Lines of code 
}); 
+0

.net 4中没有Run方法 – Tommix 2015-12-02 14:14:06

+1

已更正:任务在.net 4中可用,但在.net 4.5中支持“Task.Run”语法。 – JSideris 2016-04-27 02:30:16

相关问题