How to call the method in thread with arguments and return some value

核能气质少年 提交于 2019-12-28 12:13:27

问题


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?


回答1:


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



回答2:


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



回答3:


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



回答4:


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.




回答5:


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



回答6:


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



回答7:


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.



来源:https://stackoverflow.com/questions/2642978/how-to-call-the-method-in-thread-with-arguments-and-return-some-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!