c# – 编写可以等待的异步进程

前端之家收集整理的这篇文章主要介绍了c# – 编写可以等待的异步进程前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我一直在研究如何将我的(同步)算法转换为异步算法. (TAP)
首先,为了清楚起见,这个问题并不是关于“Async和Await做什么”(我已经阅读了Stephen Cleary的优秀帖子,例如 Async and Await(如果有人有兴趣阅读链接 – 这是非常有用的信息)

我还已经阅读了“C#简而言之”的并发章节.

这个问题不是关于异步函数如何使用等待来调用函数.我已经知道了.

不幸的是,在我阅读的几乎所有内容中,await Task.Delay(10)用于“创建异步函数”.例如:

public async Task<int> GetResult()
{
   int result= await GiveMeTheInt();

}
public async Task<int> GiveMeTheInt() //<--is async needed here? (oops! I just realize it is...
{
  await Task.Delay(100);
  return(10);
}

例如,在这个例子中,我已经理解了GetResult()函数中异步等待的魔力,但是GiveMeTheInt()的实现并不是非常有用.(它们只是将一个Delay作为一般异步函数放在那里)

所以我的问题是关于“GiveMeTheInt”类型的问题(不是那些称之为问题的人).

这个问题

如果我有一个函数编写到目前为止同步的函数,我怎么能将它转换为异步使用?

这不是一个重复的问题,我发现最接近的是Turning a Syncronous method async,其中海报被告知使用已经存在的方法的异步版本.就我而言,这不存在.

我的算法主要包括图像处理,因此实质上是扫描大数组并改变每个像素的值.就像是

void DoSomethingToImage(int[,] Image)
{
  for(int i=0;i<width;i++)
    for(int j=0;j<height;j++)
     {
       Image[i,j]=255;
     }
}

(这是一个虚构的例子,当然操作不同)

我得到的最接近的答案是将函数放在Task.Run()中,但我不确定这是否是这样做的.

任何帮助将不胜感激

解决方法

那么看看你的方法
void DoSomethingToImage(int[,] image)
{
    for (int i = 0; i < width; i++)
    {
        for (int j = 0; j < height; j++)
        {
            image[i,j] = 255;
        }
    }
}

这是异步的吗?显然不是.这只是cpu限制的工作,它会使处理器忙碌一点.因此,单独进行异步并不是一个好的假设.它应该同步运行.

如果您从应用程序的异步部分使用它,该怎么办?您当然不希望用户界面被阻止,因为您正在迭代大量像素.所以解决方案是将工作加载到另一个线程.你使用Task.Run来做到这一点:

await Task.Run(() => DoSomethingToImage(image));

因此,只要从异步方法调用DoSomethingToImage方法,就会编写它.现在,如果您只在异步上下文中使用该方法,您可能会认为将Task.Run移动到函数中可能是有意义的:

Task DoSomethingToImageAsync(int[,] image)
{
    return Task.Run(() => { … });
}

这是一个好主意吗?通常不会,因为现在你正在使该方法看起来是异步的,而事实上并非如此.它所做的只是产生一个新的线程来完成工作,然后它等待线程完成.所以现在你隐藏了那个部分,并且做一个高度同步工作的方法决定应该启动一个线程.这不是一个好主意.保持方法不变,显示它是同步的,并使调用代码负责决定应该如何运行代码.

If I have an algorithm written in a function that so far has been synchronous,how can I convert this to be used asynchronously?

所以,回到你的实际问题,这实际上很难回答.答案可能就是这样:“这取决于”.

如果一个方法执行cpu绑定工作,那么最好保持它同步并让调用代码决定如何运行它.如果您在与其他接口(网络,文件系统等)进行交互时主要进行I / O工作,那么这是使其成为异步的良好候选者,特别是考虑到许多这些接口已经提供了与之通信的异步方式他们.

关于你的“在这里需要异步吗?”问题的最后一个注意事项:你想在其中使用await时需要async关键字.仅仅存在async关键字并不会使方法异步(甚至返回类型都没有指示).

猜你在找的C#相关文章