我正在尝试等待函数结束执行某些任务。他就是我的建筑
- Windows 服务的类
- 用于与设备通信的类,实例化为"ilon"。此类可以访问另一个类,该类允许我使用 Web 服务
从窗口服务中,我正在这样做:
Item_DataColl resultSet = ilon.read("Net/LON/10/LampDali1/nviRunHours");
以下是 "ilon" 类的读取函数的定义:
internal Item_DataColl read(string UCPTName)
{
return ilonBind.invoke_command_READ("Net/LON/10/LampDali1/nviRunHours").Result;
}
Ilonbind 变量与一个类相关联,该类允许我创建与 Web 服务的连接。所以他得到了一个名为"invoke_command_read"的函数,定义为:
public async Task<Item_DataColl> invoke_command_READ(string UCPTName)
{
return await Task.Run(() => thread_command_READ_result(UCPTName));
}
在同一个类上,我终于有了这个函数:
private Item_DataColl thread_command_READ_result(string UCPTName)
{
Item_DataColl resultSet = null;
if (UCPTName != null)
{
try
{
OnProgressBarUpdate(progressBar.UnknownEnd);
resultSet = connector.command_READ(UCPTName);
readOperationDone(resultSet);
OnConsoleWriting(string.Format("[READING] Lecture réussie : {0} = {1}", ((Dp_Data)resultSet.Item[0]).UCPTname, ((Dp_Data)resultSet.Item[0]).UCPTvalue[0].Value), ILonConnectorConsoleResultType.RESULT);
}
catch (Exception e)
{
OnConsoleWriting(e.ToString(), ILonConnectorConsoleResultType.ERROR);
}
finally
{
OnProgressBarUpdate(progressBar.Invisible);
}
}
return resultSet;
}
指令"resultSet = connector.command_READ(UCPTName("运行良好,在Web服务请求的结果之前不会返回任何结果。但是我无法获得网络服务的任何结果。
我的任务使用得好吗?
我的任务使用得好吗?
不。
这是怎么回事:
- 实际操作是网络调用,因此非常适合
async
。 - 但是代理为您提供了同步 API,因此您正在阻止线程。(不好(
- 所以
invoke_command_READ
将同步API包装在一个Task.Run
中,所以它阻塞了一个线程池线程。(不好( - 然后使用
Result
read
块任务,每个请求阻塞两个线程并导致死锁。(真的很糟糕(
您的代码是同步过异步的,值得注意的是同时使用两种反模式(异步同步和异步过同步(。
要解决此问题,要么一直异步,要么一直同步。全程异步效率更高,但需要代理上的异步 API:
public async Task<Item_DataColl> invoke_command_READ(string UCPTName)
{
Item_DataColl resultSet = null;
if (UCPTName != null)
{
try
{
OnProgressBarUpdate(progressBar.UnknownEnd);
resultSet = await connector.command_READAsync(UCPTName);
readOperationDone(resultSet);
OnConsoleWriting(string.Format("[READING] Lecture réussie : {0} = {1}", ((Dp_Data)resultSet.Item[0]).UCPTname, ((Dp_Data)resultSet.Item[0]).UCPTvalue[0].Value), ILonConnectorConsoleResultType.RESULT);
}
catch (Exception e)
{
OnConsoleWriting(e.ToString(), ILonConnectorConsoleResultType.ERROR);
}
finally
{
OnProgressBarUpdate(progressBar.Invisible);
}
}
return resultSet;
}
internal Task<Item_DataColl> readAsync(string UCPTName)
{
return ilonBind.invoke_command_READ("Net/LON/10/LampDali1/nviRunHours");
}
一路同步可能会更容易,因为您的代理是同步的,而您的消费代码是同步的:
internal Item_DataColl read(string UCPTName)
{
return ilonBind.invoke_command_READ("Net/LON/10/LampDali1/nviRunHours");
}
public Item_DataColl invoke_command_READ(string UCPTName)
{
return thread_command_READ_result(UCPTName);
}