2015-06-07 16 views
2

我想執行TaskQueue。 我將任務添加到隊列中,當我調用Run()時,任務將由線程執行。代表所有方法

class Executer 
{ 
    private Queue<Task> TaskQueue; 

    private Thread thread; 

    public Executer() 
    { 
     this.TaskQueue = new Queue<QueueNode>(); 
    } 

    public void AddTask(Task task) 
    { 
     this.TaskQueue.Enqueue(task); 
    } 

    public void Run() 
    { 
     this.thread = new Thread(() => ThreadMethod); 

     this.thread.Start(); 
    } 
} 

ThreadMethod遍歷Queue並執行Task秒。

但我的問題是,我找不到Task的數據類型,因爲Task可能是一切。

假設我只想用int參數調用方法。然後,它很容易.. Task可能是這樣的:

Action<int> Task = object.AddToTheObjectCounter(5); 

但這是從無限多的只有一宗。

你能給我一個小費嗎?

我也曾經想過調用方法動態地

object.GetType().GetMethod("AddToTheObjectCounter") // ... 

,但我認爲這是不好的,因爲當我有一個拼寫錯誤的代碼編譯,但會崩潰。


提示: 我想通了,你可以用參數的變盤點調用委託(看下面的回答):

private void TestMethod() 
{ 
    Delegate function = (Func<int, int, int>)((a, b) => a * b); 
    object[] parameters = new object[] {7, 2}; 
    var result = (int)function.DynamicInvoke(parameters); 
} 

回答

3

那麼,有Delegate

private Queue<Delegate> TaskQueue; 
... 

public void AddTask(Delegate task) 
{ 
    this.TaskQueue.Enqueue(task); 
} 

然而,增加使用AddTask任務時,它不會那麼容易像以前一樣。你首先需要轉換成一個已知的委託(Func<>),然後傳遞一個參數。

obj.AddTask((Func<...>)nameOfTheMethod); 
// obj.AddTask((Func<string[], void>)Console.WriteLine); 

當你調用Delegate情況下,你不能使用operator(),因爲你不能確定什麼樣的功能實際上是。您必須改用DynamicInvoke

+0

好主意。但我有一個問題。你的代碼正在工作,但我無法調用任務。當我在我的線程中,我想用值調用函數我不能這樣做,因爲我不能使用委託任務作爲方法(錯誤)。我想我必須先把它回到Func <...> - 任何想法? – Jens

+0

這是完整的錯誤:不可調用的成員'ThreadQueue.QueueNode.Function'不能像方法一樣使用。 - 函數是這種情況下的任務 – Jens

+1

@JensHorstmann由於在談論Delegate實例時不知道返回類型或參數是什麼,所以必須使用DynamicInvoke方法。 – user35443

1

您可以使用匿名方法:

void Print(string str) { 
    Console.WriteLine("str"); 
} 

var queue = new List<Action> { 
    () => Print("Hello"), 
    () => Print(" world!"), 
    () => { 
     Print("Bla bla bla"); 
     Print("-----------"); 
    } 
}; 
for each(var task in queue) { 
    task(); 
} 

結果將會是:

Hello 
world! 
Bla bla bla 
-----------