2014-01-29 34 views
0

我想在線程池中運行一個方法。雖然建下面的代碼它給出了一個錯誤在線程池中使用方法

沒有重載「方法」匹配委託「System.Threading.WaitCallback」。

我知道哪裏有錯誤發生,但我不知道爲什麼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
namespace Thread_Pool 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      ThreadPool.QueueUserWorkItem(new WaitCallback(PrintNumbers)); 
      // PrintNumbers(); 
     } 
     static void PrintNumbers() 
     { 
      for (int i = 0; i < 10; i++) 
      { 
       Console.WriteLine(i); 
       Thread.Sleep(3000); 
      } 
     } 
    } 
} 

當上面的代碼被改寫爲以下,它工作正常。

static void PrintNumbers(object Stateinfo) 

爲什麼會發生這種情況?可以使用另一種類型(如int,float)來代替使​​用對象?

回答

1

我知道錯誤發生的地方,但我不知道爲什麼?當上述 代碼改寫如下,它工作正常

你必須遵循由WaitCallback需要,你可以看到的WaitCallback委託定義singnature。這就是爲什麼PrintNumbers需要有一個object類型的參數。

public delegate void WaitCallback(
    Object state 
) 

爲什麼會發生這種情況?而不是使用對象,我可以使用另一種類型 (如int,float)?可能嗎?

是的,你可以使用Convert.ToDouble(obj);

0

數量和類型的參數創建代表時必須匹配。

在當前版本的C#中,使用lambda表達式比使用明確鍵入的委託更容易。它使類型轉換更容易,允許通過強類型參數

ThreadPool.QueueUserWorkItem(unused => PrintNumbers())); 

int intBalue = 1; 
double doubleValue = 2; 
ThreadPool.QueueUserWorkItem(unused => Method(intValue, doubleValue)); 

,或者您還可以通過值和往常一樣:

ThreadPool.QueueUserWorkItem(state => MethodTakinObject(state)); 
1

根據MSDN

http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k(System.Threading.WaitCallback);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)&rd=true

WaitCallback委託想要Object參數:

[ComVisibleAttribute(true)] 
    public delegate void WaitCallback(Object state) 

所以,你應該提供它,即使你不打算使用它:

static void Main(string[] args) { 
    ThreadPool.QueueUserWorkItem(new WaitCallback(PrintNumbers)); 
    } 

    static void PrintNumbers(Object state) { // <- "Object state" is required here 
    ... 
    } 

如果你想離開PrintNumbers完好無損可以使用拉姆達

static void Main(string[] args) { 
    ThreadPool.QueueUserWorkItem(
     (Object state) => { // <- You have to use "Object state" 
     PrintNumbers(); 
     } 
    ); 
    } 

    static void PrintNumbers() { 
    ... 
    } 
0

WaitCallback是接受參數對象的委託。爲了使用委託你的方法有可能像這樣匹配委託簽名:

static void Main(string[] args) 
{ 
    ThreadPool.QueueUserWorkItem(new WaitCallback(PrintNumbers)); 

} 


static void PrintNumbers(object a) 
{ 
    for (int i = 0; i < 10; i++) 
    { 
     Console.WriteLine(i); 
     Thread.Sleep(3000); 
    } 
} 

,或者你可以簡單地使用lambda表達式

ThreadPool.QueueUserWorkItem(a => { PrintNumbers(); }); 

功能明智的兩種方法是相同的。只有當您打算將值傳入您的方法時,才需要「狀態」參數。