如何使用参数调用线程中的方法并返回一些值

发布于 2024-08-28 22:50:37 字数 772 浏览 9 评论 0原文

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

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

那么我如何在线程中调用它?

I like to call the method in thread with arguments and return some value here example

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

I know this above example run successfully but if method fun1 like this

public int fun1(int i,int j)
{
    int k;
    k=i+j;
    return k;
}

then how can I call this in thread?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

反差帅 2024-09-04 22:50:38

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

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

This may be another approach. Here input is passed as parameterized Thread and return type is passed in the delegate event, so that when the thread complete that will call the Delegate. This will be fine to get result when the thread completes.

 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);
        }
    }
池木 2024-09-04 22:50:38

我喜欢马克·格拉维尔的回答。您只需稍加修改即可将结果传递回主线程:

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

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);
双手揣兜 2024-09-04 22:50:38

在单独的线程中执行函数有更简单的方法:

// 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);

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

There is much simpler way to execute function in separate thread:

// 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);

This function will be executed on thread pool thread, and that logic is completely transparent to your application.
An in general, I suggest to execute such small tasks on thread pool instead of dedicated thread.

不即不离 2024-09-04 22:50:38

您可以在 Thread 构造函数上使用 ParameterizedThreadStart 重载。它允许您将对象作为参数传递给线程方法。它将是单个对象参数,因此我通常为此类线程创建一个参数类。该对象还可以存储线程执行的结果,您可以在线程结束后读取该结果。

不要忘记,在线程运行时访问该对象是可能的,但不是“线程安全的”。你知道该怎么做:)

这是一个例子:

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

You can use the ParameterizedThreadStart overload on the Thread constructor. It allows you to pass an Object as a parameter to your thread method. It's going to be a single Object parameter, so I usually create a parameter class for such threads.. This object can also store the result of the thread execution, that you can read after the thread has ended.

Don't forget that accessing this object while the thread is running is possible, but is not "thread safe". You know the drill :)

Here's an example:

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;
}
深海蓝天 2024-09-04 22:50:38

对于一些替代方案; currying:

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

或者编写您自己的捕获类型(这与您使用带有捕获变量的非方法/ lambda 时编译器为您所做的事情大致相当,但实现方式有所不同):

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

For some alternatives; currying:

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

or write your own capture-type (this is broadly comparable to what the compiler does for you when you use anon-methods / lambdas with captured variables, but has been implemented differently):

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
秋凉 2024-09-04 22:50:38

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

try backgroundWorker http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx you can pass value to the DoWork event with DoWorkEventArgs and retrive value in the RunWorkerCompleted.

薄荷梦 2024-09-04 22:50:37

您应该能够使用匿名方法或 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
});

You should be able to use an anonymous method or lambda to provide full static checking:

Thread FirstThread = new Thread(() => Fun1(5, 12));

or if you want to do something with the result:

Thread FirstThread = new Thread(() => {
    int i = Fun1(5, 12);
    // do something with i
});

but note that this "do something" still runs in the context of the new thread (but with access to the other variables in the outer method (Main) courtesy of "captured variables").

If you have C# 2.0 (and not above), then:

Thread FirstThread = new Thread((ThreadStart)delegate { Fun1(5, 12); });

and

Thread FirstThread = new Thread((ThreadStart)delegate {
    int i = Fun1(5, 12);
    // do something with i
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文