C#从任务返回数据

时间:2015-11-13 06:12:51

标签: c# .net task

您好我有以下短代码提取。代码的目的是从Task返回一个person对象并获得结果,以便它可以在main中访问。

我的代码如下,但我在编译时遇到两个错误。

  

错误2' System.Threading.Tasks.Task   multi_threaded_tasks.Program.ExecuteAsync_GetPerson()'有错了   返回类型
错误1需要对象引用   非静态字段,方法或属性   ' multi_threaded_tasks.Program.ExecuteAsync_GetPerson()'

我不确定我哪里出错了,你能提供的任何帮助都会有所帮助。 P.S如果有更好的方式返回对象,我可以接受建议,但我希望函数调用是分开的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace multi_threaded_tasks
{
    public class Person
    {
        public string first_name;
        public string last_name;
        //Constructor
        public Person()
        {
            first_name="";
            last_name="";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Main started:");
            CancellationTokenSource cancelSource;
            Task<Person> t_person = Task<Person>.Factory.StartNew(
                function: ExecuteAsync_GetPerson, 
                cancellationToken: cancelSource.Token, 
                creationOptions: TaskCreationOptions.PreferFairness, 
                scheduler: TaskScheduler.Default);

            Person main_person = t_person.Result;
            Console.WriteLine("The person first name:" + main_person.first_name);
            Console.WriteLine("The person last name:" + main_person.last_name);
            Console.WriteLine("Main Ended:");
        }

        async Task<Person> ExecuteAsync_GetPerson()
        {
            Console.WriteLine("ExecuteAsync_GetPeople started:");
            Person a_person = new Person();
            a_person.first_name="";
            a_person.last_name="";
            await Task.Delay(2000); // Wait 2 seconds
            Console.WriteLine("ExecuteAsync_GetPeople returning:");
            return a_person;
        }
    }
}

2 个答案:

答案 0 :(得分:2)

Task.Factory.StartNew具有以下定义:

public Task<TResult> StartNew(Func<TResult> function...

当你试图传递

public Task<TResult> StartNew(Func<Task<TResult>> function...

如果要启动异步方法,可以使用:

Task<Person> t_person = Task.Run(() => a());
Person main_person = t_person.Result;

答案 1 :(得分:2)

无论如何,你的代码没有多大意义。

由于这是一个带有两个方法的控制台应用程序,其中一个是应用程序入口点,因此您无法从异步方法中获得任何好处,因为您希望在主方法中获得任务结果。这意味着,主线程将被阻止,并且无法取消任何内容。

我已从您的代码中丢弃了一些垃圾,并添加了另一个示例async方法。这可能是你想要的:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class Program
{
    static async Task<Person> GetPersonAsync(CancellationToken cancellationToken)
    {
        Console.WriteLine("GetPersonAsync started.");

        var person = new Person
        {
            FirstName = "John",
            LastName = "Doe"
        };

        await Task.Delay(5000, cancellationToken); // Wait 5 seconds
        Console.WriteLine("GetPersonAsync ended.");
        return person;
    }

    static async Task TestGetPersonAsync(CancellationToken cancellationToken)
    {
        Console.WriteLine("TestGetPersonAsync started.");

        try
        {
            var person = await GetPersonAsync(cancellationToken);

            Console.WriteLine("The person first name:" + person.FirstName);
            Console.WriteLine("The person last name:" + person.LastName);
            Console.WriteLine("TestGetPersonAsync ended.");
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("TestGetPersonAsync cancelled.");
        }
    }

    static void Main(string[] args)
    {
        Console.WriteLine("Main started:");

        // let's get person asynchronously;
        // this object will contain our cancellation token;            
        var cts = new CancellationTokenSource();
        // dummy variable here is needed to aviod compiler warning,
        // since TestGetPersonAsync is async, and we will not (and cannot) await it
        var _ = TestGetPersonAsync(cts.Token);

        // if TestGetPersonAsync is not finished yet, we are going to cancel it;
        // wait for a new line
        Console.WriteLine("Press ENTER to cancel TestGetPersonAsync and to exit application.");
        Console.ReadLine();
        if (!_.IsCompleted)
        {
            cts.Cancel();
        }

        Console.WriteLine("Main ended.");
    }
}