后台线程上长时间运行的代码
本文关键字:代码 运行 长时间 线程 后台 | 更新日期: 2023-09-27 18:24:18
我的一位业务经理有以下方法:
public ImportItemsResult Import(String fullPath)
{
OleDbDataManager oleDbDataManager = new OleDbDataManager();
List<ItemInfo> importedData = oleDbDataManager.GetData<ItemInfo>(fullPath, ItemInfoMapper).ToList();
ImportItemsResult result = ValidateImportedData(importedData);
if (result.Status == OperationStatus.Success)
{
//do something with importedData in the background and return
//the result to the user right away
}
return result;
}
该代码允许用户上传.csv文件,然后对其进行解析和验证。验证后,如果所有数据都正常,则处理数据并将其保存到数据库中,否则文件将被拒绝,并在UI上向用户显示详细的错误消息。
问题:
- 假设一旦验证结果为成功状态,由于所有数据都是有效的,因此理论上处理应该顺利,这是否安全
- 是否可以在后台线程上运行处理代码并立即从该方法返回?我可以在上面代码中的if语句中这样做吗?还是需要重新构建整个内容
我之所以首先考虑这个问题,是因为我需要通过WCF web服务公开此功能,而且我不知道它要处理多长时间的数据,这可能会导致web服务超时,以防花费太长时间。有什么建议吗?
这里需要考虑以下几点:
- 唯一"安全"的假设是,所有可能出错的事情都会出错。在写入数据库时,您可能应该使用事务
- 虽然肯定可以将操作发布到线程池(即使在IIS上),但我看不出它会实现什么。您仍然需要向客户端发送响应。你还需要问几个问题:
- "长"有多长?客户等待是否可行?您可以将服务的发送超时增加到一个合理的数字
- 如果确实需要真正的异步操作,可以使用其他机制,例如双工通道或某种pub/sub。然后调用可以立即返回,客户端可以使用这些机制等待回复。但这将使设计变得更加复杂
- 您还可以选择流式传输数据,并在数据出现时对其进行处理,而不是一大块数据。点击此处阅读更多信息。这可以节省一些时间,因为你会尽快处理块(如果你需要从整体上验证数据集,这是行不通的)
验证后,仍有可能出现问题-WCF服务可能崩溃或其所在的计算机断电-您将丢失所有数据。
您需要将CSV数据持久化到非易失性介质,然后才能返回结果。此外,我会将长时间运行的代码放入一个单独的windows服务中(假设您的WCF服务是IIS托管的,否则您可以将两者结合起来),该服务只进行处理。您可以使用WCF web服务和windows服务用来存储和检索CSV数据的数据库。
您永远不应该信任参数或期望"一切都会好起来的",您应该使用try/catch语句并实现一些处理错误的东西(将一些东西记录到某个地方,将详细信息发送到客户端服务,…)
为了防止超时,您应该将WCF服务设置为支持异步操作。
顺便说一句,你的OleDbDataManager是IDisposable吗?如果是这样,您应该包含一个using关键字以防止内存泄漏。