第二十章:异步和文件I/O.(十六)

简介:

你自己的等待方法

除了通过Web或本地文件系统访问文件之外,应用程序有时需要执行自己的冗长操作。 这些操作应该在后台执行的辅助线程上运行。 虽然现在有几种方法可以做到这一点,但最好(当然最简单)使用在Xamarin.Forms和其他.NET图形环境中使用的相同的基于任务的异步模式,并定义自己的异步方法,就像其他方法一样。 这些环境。
在工作线程上运行某些代码的最简单方法是使用Task.Run和Task.Run 静态方法。 参数是一个Action对象,通常表示为lambda函数,返回值是Task。 lambda函数的主体在线程池的工作线程上运行,如果你想自己使用线程池,可以通过ThreadPool类访问它。 您可以直接在Task.Run中使用await运算符:

await Task.Run(() =>
{
    // The code that runs in a background thread.
});

虽然您可以将Task.Run本身与其他代码一起使用,但通常它用于构造异步方法。 按照惯例,异步方法的后缀为Async。 该方法返回Task对象(如果方法不返回任何值或对象)或Task 对象(如果它确实返回了某些东西)。
以下是如何创建一个返回Task的异步方法:

Task MyMethodAsync(__)
{
    // Perhaps some initialization code.
    return Task.Run(() =>
    {
        // The code that runs in a background thread.
    });
}

Task.Run方法返回您的方法也返回的Task对象。 Task.Run的Action参数可以使用传递给MyMethodAsync的任何参数,但不应使用ref或out定义任何参数。 另外,请注意您传递给MyMethodAsync的任何引用类型。 这些都可以从异步代码内部和方法外部访问,因此您可能需要实现同步,以便不会从两个线程同时访问该对象。
Task.Run调用中的代码本身可以使用await调用异步方法,但在这种情况下,您需要使用async标记传递给Task.Run的lambda函数:

return Task.Run(async () =>
{
    // The code that runs in a background thread.
});

如果异步方法返回某些内容,您将使用Task的通用形式和Task.Run的通用形式来定义方法:

Task<SomeType> MyMethodAsync(…)
{
    // Perhaps some initialization code.
    return Task.Run<SomeType>(() =>
    {
        // The code that runs in a background thread.
        return anInstanceOfSomeType;
    });
}

从lambda函数返回的值或对象将成为从Task.Run和您的方法返回的Task 对象的Result属性。
如果需要对后台进程有更多控制权,可以使用TaskFactory.StartNew而不是Task.Run来定义异步方法。
基本的Task.Run模式有一些变化,正如您将在以下几个程序中看到的那样。 这些程序计算并显示着名的Mandelbrot集。

目录
相关文章
|
Web App开发 Android开发
第二十章:异步和文件I/O.(二十三)
回到网上在本章之前,本书中唯一的异步代码涉及使用可移植类库WebRequest中唯一可用于此目的的合理类进行Web访问。 WebRequest类使用称为异步编程模型或APM的旧异步协议。 APM涉及两种方法,在WebRequest的情况下,这些方法称为BeginGetResponse和EndGetResponse。
716 0
|
JavaScript Android开发 iOS开发
第二十章:异步和文件I/O.(十二)
虽然每个方法都被定义为返回Task或Task 对象,但是方法的主体没有任何对Task或Task 的引用。相反,返回Task对象的方法只是执行一些工作,然后使用隐式return语句结束该方法。 ExistsAsync方法定义为返回Task 但返回true或false。
785 0