【发布时间】:2020-04-01 19:15:13
【问题描述】:
下面的方法假设运行(持续时间为毫秒)为案例 0:,但我看到的是该方法可能需要长达 2 秒才能运行 400 毫秒的持续时间。 Task.run 是否可能需要很长时间才能启动?如果有,有没有更好的办法?
private static async void PulseWait(int duration, int axis){
await Task.Run(() =>
{
try
{
var logaction = true;
switch (axis)
{
case 0:
var sw1 = Stopwatch.StartNew();
if (duration > 0) duration += 20; // allowance for the call to the mount
while (sw1.Elapsed.TotalMilliseconds <= duration) { } // wait out the duration
_isPulseGuidingRa = false;
logaction = false;
break;
case 1:
var axis2Stopped = false;
var loopcount = 0;
switch (SkySettings.Mount)
{
case MountType.Simulator:
while (!axis2Stopped && loopcount < 30)
{
loopcount++;
var statusy = new CmdAxisStatus(MountQueue.NewId, Axis.Axis2);
var axis2Status = (AxisStatus)MountQueue.GetCommandResult(statusy).Result;
axis2Stopped = axis2Status.Stopped;
if (!axis2Stopped) Thread.Sleep(10);
}
break;
case MountType.SkyWatcher:
while (!axis2Stopped && loopcount < 30)
{
loopcount++;
var statusy = new SkyIsAxisFullStop(SkyQueue.NewId, AxisId.Axis2);
axis2Stopped = Convert.ToBoolean(SkyQueue.GetCommandResult(statusy).Result);
if (!axis2Stopped) Thread.Sleep(10);
}
break;
default:
throw new ArgumentOutOfRangeException();
}
_isPulseGuidingDec = false;
logaction = false;
break;
}
var monitorItem = new MonitorEntry
{ Datetime = HiResDateTime.UtcNow, Device = MonitorDevice.Telescope, Category = MonitorCategory.Mount, Type = MonitorType.Data, Method = MethodBase.GetCurrentMethod().Name, Thread = Thread.CurrentThread.ManagedThreadId, Message = $"PulseGuide={logaction}" };
MonitorLog.LogToMonitor(monitorItem);
}
catch (Exception)
{
_isPulseGuidingDec = false;
_isPulseGuidingRa = false;
}
});}
显示所用时间的日志... 33652,2019:07:12:01:15:35.590,13,AxisPulse,Axis1,0.00208903710815278,400,0,True
【问题讨论】:
-
请注意,您永远不应该拥有
async void方法(事件处理程序除外)。您的PulseWait应声明为private static async Task PulseWait(...)并在调用时等待。由于整个方法体是一个单独的 Task.Run 调用,因此您也可以将其声明为private static Task PulseWait(...) { return Task.Run(() => { ... }); }。 -
您是否尝试过在 case 0: 的 while 循环之后包含由
sw1测量的经过时间的调试?而且,在 try 块的开头声明,这样你也可以在 switch case 之后调试它,看看它的值?这可能会让您知道在哪里花费的时间比预期的要长。 -
除了@Clemens 所说的之外,这还取决于您如何称呼它,来自什么样的应用程序等。尝试创建一个minimal reproducible example 来演示核心问题。
-
而
while (sw.Elapsed <= ...)循环令人眼花缭乱,它会让你的 CPU 毫无用处。查找Task.Delay()。 -
async和await使事情变得简单,并有助于提高整体性能(例如提高 Web 应用程序的整体吞吐量性能),但实际上会损害任何特定任务的性能。如果每一毫秒对您来说都很重要,您将需要自己执行低级任务,例如创建Thread(如果这确实需要在单独的线程上运行)。
标签: c# wpf async-await task-parallel-library