C# 从任务返回数据
C# Returning Data from a Task
您好,我有以下简短代码摘录。代码的目的是 return 来自 Task 的 person 对象并获得结果,以便它可以在 main 中访问。
我的代码如下,但是在编译时出现了两个错误。
Error 2 'System.Threading.Tasks.Task
multi_threaded_tasks.Program.ExecuteAsync_GetPerson()' has the wrong
return type
Error 1 An object reference is required for the
non-static field, method, or property
'multi_threaded_tasks.Program.ExecuteAsync_GetPerson()'
我不确定我哪里出错了,您能提供的任何帮助都会有所帮助。 P.S 如果有更好的方法 return 对象,我愿意接受建议,但我希望函数调用是分开的。
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;
}
}
}
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;
无论如何,您的代码没有多大意义。
由于这是一个控制台应用程序,有两个方法,其中一个是应用程序入口点,您无法从异步方法中获得任何好处,因为您想在主方法中获取任务结果。这意味着,主线程将被阻塞并且无法取消任何操作。
我从您的代码中删除了一些垃圾并添加了另一个示例 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.");
}
}
您好,我有以下简短代码摘录。代码的目的是 return 来自 Task 的 person 对象并获得结果,以便它可以在 main 中访问。
我的代码如下,但是在编译时出现了两个错误。
Error 2 'System.Threading.Tasks.Task multi_threaded_tasks.Program.ExecuteAsync_GetPerson()' has the wrong return type
Error 1 An object reference is required for the non-static field, method, or property 'multi_threaded_tasks.Program.ExecuteAsync_GetPerson()'
我不确定我哪里出错了,您能提供的任何帮助都会有所帮助。 P.S 如果有更好的方法 return 对象,我愿意接受建议,但我希望函数调用是分开的。
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;
}
}
}
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;
无论如何,您的代码没有多大意义。
由于这是一个控制台应用程序,有两个方法,其中一个是应用程序入口点,您无法从异步方法中获得任何好处,因为您想在主方法中获取任务结果。这意味着,主线程将被阻塞并且无法取消任何操作。
我从您的代码中删除了一些垃圾并添加了另一个示例 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.");
}
}