我正在尝试创建一种类型的“即发即弃”功能,而我并不关心该功能的完成或结果。为此,我在该函数的主体中使用了Task.Run()
,因此我可以同时运行它并立即从中返回。
我认为必须提及的是,该运行是IIS应用程序。
类似这样的东西:
void ReallyImportantFunction()
{
//Do really important work
NotSoImportantWork("some data");
//Do really important work
}
void NotSoImportantWork(string data)
{
Task.Run(() =>
{
try
{
//Do something here with the data
}
catch (Exception ex)
{
//Log exception do not throw
}
});
}
答案 0 :(得分:1)
在没有更多信息的情况下很难回答这个问题,但是我认为您误解了Task.Run()
和异步代码的使用。如果它是无关紧要的工作,并且您不关心结果或完成情况,则可能会首先询问是否需要在此处运行它。其次,Task.Run()
通常用于执行长时间运行的代码,否则可能会阻塞UI线程。如果您要进行数据库调用或写入文件系统,则可以将此逻辑放入“任务”。一个例子是
void ReallyImportantFunction()
{
try
{
//Do really important work
Task.Run(() => NotSoImportantWork("some data"));
//Do really important work
}
catch (Exception ex)
{
/ Handle the exception
}
}
void NotSoImportantWork(string data)
{
//Do something here with the data
}
但是,如果您实际使用 ever 来使用数据,或者您的计算 ever 有任何副作用或变异,这就会使您面临数据竞争。如果您说的是正确的,但您从未看过结果,那么我可能会问为什么它是方法的开始。如果您永远不会使用重要的事物,为什么还要在它们之间计算真正不重要的事物呢?如果您正在使用结果或对所需内容进行突变,则代码可以正确等待结果。
async void ReallyImportantFunction()
{
try
{
//Do really important work
var myResult = await IOIntensiveWork("some data");
//Do really important work
}
catch (Exception ex)
{
// Handle the exception
}
}
Task<MyResult> IOIntensiveWork(string data)
{
//Do something here with the data
}
如果您也可以避免使用async void
方法,通常会比较干净,尽管这不一定有问题。只记得要始终检查异常。
编辑:根据您在评论中所写内容,我认为将NotSoImportantWork()
包装在任务中是有意义的。这并不是因为它不重要,而是因为您显然正在进行网络呼叫,并且在与您控制范围之外的服务进行通信时可能会发生各种问题。
因此,您可以只从Task.Run(() => NotSoImportantWork("..."));
中ReallyImportantFunction()
,但是要注意在哪里捕获异常以及如果应该发生代码,代码可能在哪里退出。我可能更愿意在此处而不是在Task.Run()
中启动NotSoImportantWork()
,因为您可能会使用Task.Run(...).ConfigureAwait(false);
从代码中挤出最后的性能(这在很大程度上取决于您的代码代码结构化。)
根据要从何处启动任务,可以使用...ConfigureAwait(false);
来表示操作完成后不需要返回当前上下文。有时可以提高性能。只要有意义,请尝试并使用它。有关更多信息,请查看以下内容:When correctly use Task.Run and when just async-await
在代码中没有更多上下文的情况下,很难比这更详细。希望对您有帮助!