我有两个async-await
连接到同一个TCP端口。
RSP
每20000ms
轮询一次。
SP
每个500ms
轮询一次。
另一种方法RP
,无论何时调用它都会轮询,因此它可以是随机的。
现在,只要几次调用RP
,整个系统就会冻结。
我想知道信号量或 Mutex 在这种情况下是否更合适,我应该如何使用它。
我查看了信号量的示例,但似乎大多数都使用了一种方法,但尝试同时运行其中的5种。我如何在两种不同的方法中使用它们?
static SemaphoreSlim _sem = new SemaphoreSlim(1, 1);
public async void RSP()
{
await Task.Run(() =>
{
while (true)
{
_sem.Wait();
//DoWork
_sem.Release();
Thread.Sleep(20000);
}
}
);
}
public async void SP(CancellationToken token)
{
await Task.Run(() =>
{
while (true)
{
try
{
if (token.IsCancellationRequested)
{
return;
}
_sem.Wait();
//DoWork
_sem.Release();
}
catch (Exception)
{
if (token.IsCancellationRequested)
{
return;
}
break;
}
Thread.Sleep(500);
}
});
}
答案 0 :(得分:0)
当您(默默地)忽略Exception
处理程序中的catch
时,会发生不好的事情。
try
{
//...
_sem.Wait();
//if an exception happens here
//you won't know about it because
//logic in the catch means it will
//be ignored.
//Even worse... the line below won't be called
_sem.Release();
}
catch (Exception)
{
//...
break; //oh s**t. how will we ever know?
}
这是死锁的完美配方。
如何改进?
try
{
//...
_sem.Wait();
try
{
//do work
}
finally
{
_sem.Release(); //called, even if there's an exception
}
}
catch (Exception)
{
//...
//this is just sloppy. never ignore ALL exceptions
//fix this.
break;
}
顺便说一下,您似乎正在进行大量的同步阻止操作,并将它们与async await
混合使用。这并不意味着它的使用方式。如果您没有使用任务/异步网络方法,那么您可以使用Thread.Sleep
来使用await Task.Delay
。 SemaphoreSlim
提供了使用WaitAsync
方法等待信号量的任务/异步支持。您的代码中可能没有任何内容需要通过等待,睡眠或同步IO来停止执行。正确学习异步并停止使用等待或睡眠的线程来捆绑你的ThreadPool。