当前位置:  开发笔记 > 编程语言 > 正文

如何阻止异步作业完成

如何解决《如何阻止异步作业完成》经验,为你挑选了1个好方法。

我正在使用一个C#库,它使用NVIDIA的CUDA将某些工作任务卸载到GPU.一个例子是使用扩展方法将两个数组一起添加:

float[] a = new float[]{ ... }
float[] b = new float[]{ ... }
float[] c = a.Add(b);

此代码中的工作是在GPU上完成的.但是,我希望它是异步完成的,这样只有在需要结果时才会在CPU块上运行代码(如果结果还没有在GPU上完成).为此,我创建了一个隐藏异步执行的ExecutionResult类.在使用中,这看起来如下:

float[] a = new float[]{ ... }
float[] b = new float[]{ ... }
ExecutionResult res = a.Add(b);
float[] c = res; //Implicit converter

在最后一行,程序将阻止数据是否已准备就绪.我不确定在ExecutionResult类中实现这种阻塞行为的最佳方法,因为我对同步线程和那些类型的东西不是很熟悉.

public class ExecutionResult
{
    private T[] result;
    private long computed = 0;

    internal ExecutionResult(T[] a, T[] b, Action> f)
    {
        f(a, b, UpdateData); //Asych call - 'UpdateData' is the callback method
    }

    internal void UpdateData(T[] data)
    {
        if (Interlocked.Read(ref computed) == 0)
        {
            result = data;
            Interlocked.Exchange(ref computed, 1);
        }
    }

    public static implicit operator T[](ExecutionResult r)
    {
        //This is obviously a stupid way to do it
        while (Interlocked.Read(ref r.computed) == 0)
        {
            Thread.Sleep(1);
        }

        return result;
    }
}

传递给构造函数的Action是一个异步方法,它在GPU上执行实际工作.嵌套的Action是异步回调方法.

我主要担心的是如何最好/最优雅地处理转换器中的等待,以及是否有更合适的方法来解决整个问题.如果我需要详细说明或进一步解释,请发表评论.



1> Jon Skeet..:

我不清楚这是一个你正在实现的框架多少,以及你在调用其他代码的程度,但我会尽可能遵循.NET中的"普通"异步模式.

推荐阅读
夏晶阳--艺术
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有