我喜欢在带有参数的线程中调用该方法,并在此处返回一些值示例
class Program
{
static void Main()
{
Thread FirstThread = new Thread(new ThreadStart(Fun1));
Thread SecondThread = new Thread(new ThreadStart(Fun2));
FirstThread.Start();
SecondThread.Start();
}
public static void Fun1()
{
for (int i = 1; i <= 1000; i++)
{
Console.WriteLine("Fun1 writes:{0}", i);
}
}
public static void Fun2()
{
for (int i = 1000; i >= 6; i--)
{
Console.WriteLine("Fun2 writes:{0}", i);
}
}
}
我知道上面的例子运行成功但是如果方法fun1像这样
public int fun1(int i,int j)
{
int k;
k=i+j;
return k;
}
然后如何在线程中调用它?
答案 0 :(得分:24)
您应该能够使用匿名方法或lambda来提供完整的静态检查:
Thread FirstThread = new Thread(() => Fun1(5, 12));
或者如果你想对结果做点什么:
Thread FirstThread = new Thread(() => {
int i = Fun1(5, 12);
// do something with i
});
但请注意,这个“做某事”仍然在新线程的上下文中运行(但是可以访问外部方法中的其他变量(Main
),这是由“捕获的变量”提供的。)
如果你有C#2.0(而不是上面的话),那么:
Thread FirstThread = new Thread((ThreadStart)delegate { Fun1(5, 12); });
和
Thread FirstThread = new Thread((ThreadStart)delegate {
int i = Fun1(5, 12);
// do something with i
});
答案 1 :(得分:7)
这可能是另一种方法。这里输入作为参数化传递,并且在委托事件中传递返回类型,这样当线程完成时将调用Delegate。当线程完成时,这将很好地获得结果。
public class ThreadObject
{
public int i;
public int j;
public int result;
public string Name;
}
public delegate void ResultDelegate(ThreadObject threadObject);
public partial class Form1 : Form
{
public event ResultDelegate resultDelete;
public Form1()
{
InitializeComponent();
resultDelete += new ResultDelegate(resultValue);
}
void resultValue(ThreadObject threadObject)
{
MessageBox.Show("Thread Name : " + threadObject.Name + " Thread Value : " + threadObject.result);
}
private void button1_Click(object sender, EventArgs e)
{
ThreadObject firstThreadObject = new ThreadObject();
firstThreadObject.i = 0;
firstThreadObject.j = 100;
firstThreadObject.Name = "First Thread";
Thread firstThread = new Thread(Fun);
firstThread.Start(firstThreadObject);
ThreadObject secondThreadObject = new ThreadObject();
secondThreadObject.i = 0;
secondThreadObject.j = 200;
secondThreadObject.Name = "Second Thread";
Thread secondThread = new Thread(Fun);
secondThread.Start(secondThreadObject);
}
private void Fun(object parameter)
{
ThreadObject threadObject = parameter as ThreadObject;
for (; threadObject.i < threadObject.j; threadObject.i++)
{
threadObject.result += threadObject.i;
Thread.Sleep(10);
}
resultValue(threadObject);
}
}
答案 2 :(得分:7)
我喜欢Mark Gravell的回答。只需稍加修改,您就可以将结果传递回主线程:
int fun1, fun2;
Thread FirstThread = new Thread(() => {
fun1 = Fun1(5, 12);
});
Thread SecondThread = new Thread(() => {
fun2 = Fun2(2, 3);
});
FirstThread.Start();
SecondThread.Start();
FirstThread.Join();
SecondThread.Join();
Console.WriteLine("Fun1 returned {0}, Fun2 returned {1}", fun1, fun2);
答案 3 :(得分:1)
在单独的线程中执行函数有更简单的方法:
// Create function delegate (it can be any delegate)
var FunFunc = new Func<int, int, int>(fun1);
// Start executing function on thread pool with parameters
IAsyncResult FunFuncResult = FunFunc.BeginInvoke(1, 5, null, null);
// Do some stuff
// Wait for asynchronous call completion and get result
int Result = FunFunc.EndInvoke(FunFuncResult);
此函数将在线程池线程上执行,该逻辑对您的应用程序完全透明。 总的来说,我建议在线程池而不是专用线程上执行这样的小任务。
答案 4 :(得分:0)
您可以在Thread构造函数上使用ParameterizedThreadStart重载。它允许您将Object作为参数传递给线程方法。它将是一个Object参数,所以我通常为这样的线程创建一个参数类。这个对象也可以存储线程执行的结果,你可以在线程结束后读取。
不要忘记在线程运行时访问此对象是可能的,但不是“线程安全”。你知道演习:)
以下是一个例子:
void Main()
{
var thread = new Thread(Fun);
var obj = new ThreadObject
{
i = 1,
j = 15,
};
thread.Start(obj);
thread.Join();
Console.WriteLine(obj.result);
}
public static void Fun(Object obj)
{
var threadObj = obj as ThreadObject;
threadObj.result = threadObj.i + threadObj.j;
}
public class ThreadObject
{
public int i;
public int j;
public int result;
}
答案 5 :(得分:0)
对于某些替代方案;钻营:
static ThreadStart CurryForFun(int i, int j)
{ // also needs a target object if Fun1 not static
return () => Fun1(i, j);
}
Thread FirstThread = new Thread(CurryForFun(5, 12));
或编写自己的捕获类型(这与编译器为您使用带有捕获变量的anon-methods / lambdas时的操作大致相当,但实现方式不同):
class MyCaptureClass
{
private readonly int i, j;
int? result;
// only available after execution
public int Result { get { return result.Value; } }
public MyCaptureClass(int i, int j)
{
this.i = i;
this.j = j;
}
public void Invoke()
{ // will also need a target object if Fun1 isn't static
result = Fun1(i, j);
}
}
...
MyCaptureClass capture = new MyCaptureClass(5, 12);
Thread FirstThread = new Thread(capture.Invoke);
// then in the future, access capture.Result
答案 6 :(得分:0)
尝试backgroundWorker http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx您可以使用DoWorkEventArgs将值传递给DoWork事件,并在RunWorkerCompleted中传递值。