链接异步/等待

时间:2019-09-02 06:42:00

标签: c# async-await task-parallel-library

我开发了许多算法,它们通过使用常规$('div.col').height( let m = 50 // The margin between between the child div's. $('div.container-fluid').height() - $('div.resizable-widget').height() - m ) 自己完成了大部分线程。方法始终如下

Threads

使用上面的方法,索引被推入某个消息队列,该消息队列由单个算法的线程处理。所以最后算法的界面是这样的:

float[] GetData(int requestedItemIndex)

该示例非常原始,但仅是为了提供线索。问题是我可以链接目前可以与我的解决方案配合使用的算法。如您所见,每个GetData都调用父算法的另一个GetData。当然,这可能会变得更加复杂,并且当然需要有一个最终的父级作为数据源,否则我会得到StackOverflowExceptions。

现在,我尝试通过使用异步/等待更改此行为。我的问题是,如果我重写代码,我将得到如下内容:

public abstract class AlgorithmBase
{
    private readonly AlgorithmBase Parent;

    private void RequestQueue()
    {
    }

    public float[] GetData(int requestedItemIndex) => Parent.GetData(requestedItemIndex);
}

现在,我已经链接了算法,每个新算法都跨越了另一个Task,这需要很多次才能完成。

所以我的问题是,是否可以通过使用defines接口将下一个任务嵌入已运行的任务中?

2 个答案:

答案 0 :(得分:1)

无需显式使用Task.Run。您应该避免这种情况,并将选择权留给AlgorithmBase类的使用者。

因此,您可以非常类似地实现async版本,其中Task对象将从父对象传播到子对象:

public abstract class AlgorithmBase
{
    private readonly AlgorithmBase Parent;

    private void RequestQueue()
    {
    }

    public Task<float[]> GetDataAsync(int requestedItemIndex) 
         => Parent.GetDataAsync(requestedItemIndex);
}

最终,某些“父项”将以与同步对应项相同的方式实现GetDataAsync

public class SortAlgorithm : AlgorithmBase
{
    public override async Task<float[]> GetDataAsync(int requestedItemIndex)
    {
        // asynchronously get data 
        var data = await Parent.GetDataAsync(requestedItemIndex);

        // synchronously process data and return from asynchronous method
        return this.ProcessData(data);
    }

    private float[] ProcessData(float[] data)
    {
    }
}

最后,SortAlogirthm的使用者可以决定是否await,还是只是抛弃它。

var algo = new SortAlgorithm();

// asynchronously wait until it's finished
var data = await algo.GetDataAsync(1);

// start processing without waiting for the result
algo.GetDataAsync(1);

// not needed - GetDataAsync already returns Task, Task.Run is not needed in this case
Task.Run(() => algo.GetDataAsync(1));

答案 1 :(得分:0)

在等待库代码时,通常每次都想avoid capturing and restoring the context,尤其是在循环中等待时。因此,要提高您的库的性能,请考虑在所有await上使用.ConfigureAwait(false)