对我来说,理解下面的异步用法有点困难。我在本地测试过,发现两者的实际结果是一样的,但不知道两者应该在哪些场景下使用,是否存在潜在问题?
最基本的要求是有一个属性可以做一些事情。如果为true,它将启动一个线程(不干扰当前线程)执行循环操作,如果为false,它将关闭循环操作。
public bool IsMaster
{
get { return _isMaster; }
set
{
_isMaster = value;
if (_isMaster)
{
if (_httpTask == null || _httpTask.IsCompleted || _httpTask.IsFaulted)
{
_httpTask = Task.Run(async () => await HandleHesApiRequest());
Logobject.LogDebug($"[HttpService]Master core,HTTP listenning started");
}
}
else
{
while (true)
{
//dispose resource
if (_httpTask == null || _httpTask.IsCompleted || _httpTask.IsFaulted)
{
Stop();
Logobject.LogDebug($"[HttpService]Worker core,HTTP listenning stopped");
break;
}
Thread.Sleep(2000);
}
}
}
}
字符串
异步方法是这样的
public async Task HandleHesApiRequest()
{
int relayCount = 2;
while (true)
{
if (!IsMaster)
{
Logobject.LogDebug($"[HttpService]Changed to worker core,HTTP listenning stopping...");
break;
}
else
{
//Do some job whether 'IsMaster==true'
}
await Task.Delay(xx)
}
Logobject.LogDebug($"[HttpService]Exit service...");
await Task.CompletedTask;
}
型
问题是我不明白
_httpTask =Task.Run(()=>HandleHesApiRequest());
型
和/或
_httpTask = Task.Run(async () => await HandleHesApiRequest());
型
SDK是.Net Core 3.1
3条答案
按热度按时间hof1towb1#
如前所述,it is justifiable在本例中省略了委托上的
async
,因为它没有做任何有用的事情。然而,无论如何,你不应该在setter中运行如此复杂的东西,当然你也不应该仅仅因为它是一个setter就阻止循环等待任务。相反,创建一个单独的
Set
方法,即async
和await
任务。这还允许任务上的异常正确地冒泡。另外,你的
if
逻辑好像不对,取消的时候好像应该反过来。IsCompleted
包括IsFaulted
。字符串
rvpgvaaj2#
对于给定的例子,没有真实的的区别。对于一个只调用另一个方法的方法来说,是否等待返回的任务应该没有什么实际的区别。
不过,你最好用个计时器。“循环睡眠”是一个反模式,而“循环任务.延迟”稍微好一点,它可能仍然不是最好的方法。
一些基本的经验法则是:
1.如果您正在执行IO操作,例如从磁盘阅读或发出http请求,请使用Async模式。
1.如果你正在进行大量的计算,请使用后台线程,即第一个月
1.如果你定期做任何事情,你应该使用timer。
在某些情况下,您可能希望合并模式,例如使用异步模式来等待缓慢的计算,或者将periodic timer与异步代码一起使用。但这实际上取决于具体情况,示例中没有足够的细节来提供任何具体的建议。
我也会推荐阅读关于这个主题的很多内容。多线程和async/await都是相当复杂的主题。Dissecting the async methods in C#和There Is No Thread是一些不错的读物,但还有很多其他不错的资源。
rbpvctlc3#
_httpTask =Task.Run(()=>HandleHesApiRequest());
:它正在向Task.Run传递一个同步委托,这意味着Task.Run方法将返回一个Task,该Task表示HandleHesApiRequest的完成。_httpTask = Task.Run(async () => await HandleHesApiRequest());
:它传递一个异步委托给Task.Run,这意味着Task.Run方法将返回一个Task,该Task表示异步lambda的完成,而异步lambda的完成则等待HandleHesApiRequest的完成。