使方法本身异步化

4
我有一个像这样的方法:
public  List<List<string>>  GroupedNodes(string URL, params string[] XPathes)
{
    //Load HTML Source
    HtmlWeb loader = new HtmlWeb();
    HtmlAgilityPack.HtmlDocument doc = loader.Load(URL);

    //some other codes ...

    //Return result as a List of list
    return grouped;
}

我使用HtmlAgilityPack从网址中获取HTML源代码。
但是当我使用这种方法时,它会导致程序冻结
我知道在UI中调用此方法时可以使用多线程,但是我想以异步和自适应的方式编写我的方法,并且当我们使用它时,它能够正常运行而不会冻结。
我的意思是,如果有人使用我的方法并且他/她不知道多线程,我希望他/她的程序不会冻结。换句话说,我不想使用线程或任务来调用我的方法!
3个回答

1
通常,正确的方法是使用你正在使用的 IO 方法的 async 等效方法(如 Load())。但是,HtmlAgilityPack 似乎不支持异步操作(至少在其 .Net 4.5 版本中不支持)。
这意味着最好的选择是在另一个线程上运行你的方法,并要求调用者使用 async-await
例如,实现可能如下所示:
private List<List<string>> GroupedNodes(string URL, params string[] XPathes)
{
    //Load HTML Source
    HtmlWeb loader = new HtmlWeb();
    HtmlAgilityPack.HtmlDocument doc = loader.Load(URL);

    //some other codes ...

    //Return result as a List of list
    return grouped;
}

public Task<List<List<string>>> GroupedNodesAsync(string URL, params string[] XPathes)
{
    return Task.Run(() => GroupedNodes(URL, XPathes));
}

如果不使用 async-await,没有好的方法使你的方法不会阻塞调用线程。


0

使用AsyncCallBack

看这里,我认为这个答案的一部分就是您想要的:回调模型

什么是AsyncCallback?

稍加改变和思考,您可以将其与您的方法一起使用。


这个答案太笼统并且违反了在C#中普遍使用"async-await"的惯例。 - svick

-2

看起来你可能没有很好地理解任务和异步的概念。异步方法是由于IO/网络绑定操作的本质而产生的,这些操作可能需要一些时间才能完成,而你必须等待其完成。多年来,事件和回调被用来解决这些问题,而现在异步和等待很好地发挥了作用。

回到问题上,当你在UI线程上同步运行异步任务时,你必须等待它的完成,而这种冻结就是结果,否则如果你不想冻结,你必须在UI调度程序或MVVM架构中的ViewModel上使用异步方法。


Ramin,我认为你的答案太抽象了,对于提问者或其他将来阅读它的人都没有任何帮助。 - Theodor Zoulias
@TheodorZoulias 谢谢你的澄清,我感觉他的问题更多是概念性的而不是技术/代码方面的,所以我试图向他解释发生了什么以及为什么我们会在地球上使用异步,当然如果他想要更多的描述或代码,我很乐意提供。但我无法理解为什么会被踩。 - RaminMT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接