2012-06-27 104 views
2

有一個是我的程序不斷打電話,所以我想它擰使得GUI不凍結,而它處理其業務方法。其他類的線程方法?

Thread t = new Thread(Class2.ArrayWorkings(1, MyGlobals.variable1)); 
    t.start(); 
     int[] localVariable1 = ??// I want to move the value returned from the method into localVariable1. 

目前我的錯誤是:

的最佳重載方法匹配 'System.Threading.Thread.Thread(System.Threading.ParameterizedThreadStart)' 有一些無效參數

&

參數1:不能從「方法組」轉換爲「System.Threading.ParameterizedThreadStart」

ç urrently這樣做,不必穿線,如:做這件事的

int[] localVariabl1 = Class2.ArrayWorkings(1, MyGlobals.variable1); 
+0

當方法沒有完成執行時,你會怎麼做呢?(您的直接錯誤是由於您創建線程的方式所致,而且您不關閉構造函數調用的事實也無濟於事......) –

+0

哪個框架? Winform的? WPF/Silverlight的? –

+0

這是winforms Steve – user1166981

回答

9

您可以通過使用一個lambda修復構造:

Thread t = new Thread(() => Class2.ArrayWorkings(1, MyGlobals.variable1)); 

但是,這並不讓你(作爲喬恩指出)得到的結果馬上 - 否則你正在寫同步碼再次。您可以改爲尋找某種回調;想必你需要回到UI線程,所以:

Thread t = new Thread(() => { 
    // this runs on the worker 
    int[] localVariabl1 = Class2.ArrayWorkings(1, MyGlobals.variable1); 
    this.Invoke((MethodInvoker)delegate { 
     // now we're back on the UI thread! 
     update the UI from localVariabl1 
    }); 
}); 
t.Start() 

我可能會建議使用線程池,但:

ThreadPool.QueueUserWorkItem(delegate { 
    // this runs on the worker 
    int[] localVariabl1 = Class2.ArrayWorkings(1, MyGlobals.variable1); 
    this.Invoke((MethodInvoker)delegate { 
     // now we're back on the UI thread! 
     update the UI from localVariabl1 
    }); 
}); 
+0

然後,我開始在for循環中使用locla變量,以便爲變量獲取「不存在於當前上下文中」的錯誤,如果使用線程,我應該使這些全局變量還是某些東西? – user1166981

+0

@ user1166981需要看一個例子;在我發佈的內容中,變量**對於UI回調代碼是可用的,它是一個「捕獲變量」。和不:使其不全球 –

+0

我實際上使用該變量繪製使用DirectX,沒有其他任何事情正在發生,直到方法完成。這一切都發生在onpaint事件中,我所有的顯示邏輯都是(頂點計算),我稱之爲密集型方法 - 這可能是我的問題的一部分嗎? – user1166981

2

一種方法是如下:

ThreadStart starter = delegate { Class2.ArrayWorkings(1, MyGlobals.variable1); }; 
var thread = new Thread(starter); 
thread.Start(); 

編輯:剛纔看到你也想捕獲來自線程的返回值。 您可能需要使用ThreadPool.QueueUserWorkItem在馬克的答覆中提到,你可能想看看

東西是.​​NET框架4.5(仍處於發佈候選) 讓生活與異步編程更容易。

await operator in .NET 4.5

+0

從那你如何檢索返回值? – user1166981

2

您gotto把的ThreadStart代表。如果你真的不希望UI受到影響,你應該使用BackgroundWorker Class。

+0

沒有什麼特別的關於'BackgroundWorker'的神奇功能,如果它有幫助,那很好,但是沒有什麼「你應該使用」它。 –

+0

是的。沒有後臺工作人員的處理。因爲你必須自己做很多事情。這是更簡單的方法,也有很好的控制。 –

+0

meh,一次調用'Invoke'或'BeginInvoke' ...坦率地說,'BackgroundWorker'是更多的工作 –

1

任務提供用於執行異步工作,最終將返回一個值,一個簡單的界面。 A爲例Task<string>是,(最終)返回一個字符串,其中一個Task<int[]>將返回一個整數數組的任務。

int[] localVariable1; 

// start the task 
Task<int[]> myTask = Task.Factory.StartNew<int[]>(() => Class2.ArrayWorkings(1, MyGlobals.Variable1); 

// when it is finished get the result and place in local variable 
myTask.OnCompleted(task => localVariable1 = task.Result;); 

如果您想在異步操作完成後更新UI組件,則必須使用Invoke(用於winforms)。這使您可以使用UI線程上的對象(如按鈕和標籤)。

myTask.OnCompleted(task => localVariable1.Invoke(new Action(() => 
    localVariable1.Value = task.Result;))); 
+0

嗨,我實際上沒有使用任何winforms的東西,它是一個directx控件,我通過更新onpaint事件。該方法也是從onpaint事件中調用的,然後在完成之後,我使用它來計算vertix math並開始場景/結束場景。 – user1166981