在多线程场景中查看返回值的示例

时间:2009-07-16 16:38:59

标签: c#

我有一个方法。我想返回一个不是来自主线程而是来自单独线程的值。你能给出一个例子吗?

5 个答案:

答案 0 :(得分:0)

Jon Skeet一般在.net内的线程上有一个很好的article。但是,如果您想更具体地回答更具体的问题,请发布更多详细信息。

编辑: 要使方法在主线程以外的线程中返回,您只需要第二个线程。在该线程中完成的所有操作都将是方法调用并在该单独的线程中返回。在线程之间传递数据是一个更复杂和技巧的主题。作为一个起点,我再次指出Jon Skeet的article以获得良好的基础理解。除此之外,有一些有用的一般原则,例如Asynchronous调用和BackgroundWorkers(也见here)可能非常有用,但这些只是选项,有很多方法可以做到这一点,以及如何做到这一点非常依赖于这种情况。

答案 1 :(得分:0)

最简单的方法是查看Background Worker

 //set up your BackgroundWorker
 BackgroundWorker worker = new BackgroundWorker();
 worker.DoWork += new DoWorkEventHandler(worker_DoWork);
 worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
 worker.RunWorkerAsync();


        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Result != null)
            {
                //process your e.Result
            }
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            //do your work here

            e.Result = "testing"; //set the result to any object
        }

答案 2 :(得分:0)

这就是你要求的:

class DoSomething
{
string result;
    public void RunAsync()
    {
        var t = new BackgroundWorker();
        t.DoWork += (sender, e) =>
        {
            result = string.Empty; // your code goes here instead of string.empty
        };
        t.RunWorkerCompleted += Finished;//BackgroundWorkerFinished(sender, e);
        t.RunWorkerAsync();
    }
    public void Finished(object sender, RunWorkerCompletedEventArgs e)
    {
        //result has been set, now what?


    }
}

一旦你做到这一点,这变得更有用:

public static void RunAsync(this Action ActionToAsync, Action<object, RunWorkerCompletedEventArgs> FinishedAction)
    {
        var t = new BackgroundWorker();
        t.DoWork += (sender, e) => ActionToAsync();
        t.RunWorkerCompleted += (sender, e) => FinishedAction.Invoke(sender,e);//BackgroundWorkerFinished(sender, e);
        t.RunWorkerAsync();
    }

答案 3 :(得分:0)

你的问题没有意义。方法在同一个线程上直接向调用它的方法返回一个值。

编辑:如果您希望方法为WinForms上的UI线程提供值,可以调用BeginInvoke方法。例如,

//In some event handler, such as button1_Click:
ThreadPool.QueueUserWorkItem(delegate {
    //This code runs on a background thread.
    //In it, you can do something that takes
    //a long time without freezing the UI. If
    //you need to interact with the UI from 
    //the background thread, use the Invoke
    //method, like this:

    var text = (string)Invoke(new Func<string>(() => textBox1.Text));

    //I assume you'd want to do something more meaningful.
    var result = text + Environment.NewLine + new String(text.Reverse().ToArray());

    //To send the result back to the UI thread, call BeginInvoke:
    BeginInvoke(new Action(delegate {
        //This code is back on the UI thread,
        //but it can still use the variables
        //defined earlier.
        label1.Text = result;
    });
});

答案 4 :(得分:0)

为了让你的方法从另一个线程返回一些东西,那个其他线程必须“拥有”某个东西,并且必须指出“某事”已准备好返回。没有一般情况,但有具体情况。例如,生产者/消费者问题,其他线程产生一些东西并将其放入队列,第一个线程等待,直到队列中有东西,取出它,然后返回它。

在异步ASP.NET页面中可以看到另一个有点意义的情况。页面正常开始,发出一个或多个异步操作,然后返回到ASP.NET。在完成所有异步操作之前,它什么都不做。然后,ASP.NET在页面中调用一个方法来检索这些操作的结果,并在页面的其余部分中使用它们。

您可能会发现这两种情况非常不同。那是因为你似乎问了一个“学习”问题,相当于“我想知道一个方法总是必须从同一个线程获得它的返回值吗?”但这不是你在现实生活中必须做的事情,不是真的。

我将补充一点,Ada编程语言包括这样的东西 - 实际上使用的人必须说它是否有用。如果我没记错的话,一个任务可以与另一个任务集合,并在它们之间传递数据。