7

我喜欢用参数调用线程中的方法并在此处返回一些值示例

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;
}

那我怎么能在线程中调用它呢?

4

7 回答 7

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
});
于 2010-04-15T05:56:24.900 回答
7

这可能是另一种方法。这里输入作为参数化线程传递,返回类型在委托事件中传递,因此当线程完成时将调用委托。当线程完成时,这将很好地得到结果。

 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);
        }
    }
于 2010-04-21T12:13:45.753 回答
7

I like Mark Gravell's answer. You can pass your result back out to the main thread with just a little modification:

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);
于 2011-04-19T17:31:01.357 回答
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);

此函数将在线程池线程上执行,并且该逻辑对您的应用程序是完全透明的。一般来说,我建议在线程池而不是专用线程上执行这样的小任务。

于 2010-04-23T09:02:06.963 回答
0

您可以在 Thread 构造函数上使用 ParameterizedThreadStart 重载。它允许您将对象作为参数传递给您的线程方法。这将是一个单独的 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;
}
于 2010-04-21T09:57:17.210 回答
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
于 2010-04-21T10:07:01.827 回答
0

尝试 backgroundWorker http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx您可以使用 DoWorkEventArgs 将值传递给 DoWork 事件,并在 RunWorkerCompleted 中检索值。

于 2010-04-23T09:53:54.710 回答