是否可以在不等待结果的情况下在新线程中调用非托管资源的dispose()? 我有一个使用2个非托管资源的异步函数。 (rdKafka制片人和主题)。经过一些测试和时间戳测量,我意识到他们的Dispose功能需要很长时间才能完成,所以我想在不同的线程中调用这些资源的dispose(),而不是“等待”他的结果。 意思是,我想尽快得到结果,让一些线程处理dispose()。
这是我的代码:
public async Task<bool> ProduceMessage(object someobject)
{
var result = true;
using (var producer = new Producer(_kafkaOptions.Uri)) {
using (var topic = producer.Topic(_kafkaOptions.Topic, topicConfig)) {
var report = topic.Produce(someobject);
await report.ContinueWith(task =>
{
if (task.Status == TaskStatus.RanToCompletion) {
//if produce succeed and task completed, return true
_logger.LogDebug("Producer Succeed");
result = true;
} else {
HandleError(task);
result = false;
}
});
答案 0 :(得分:0)
不要将它们放在using
声明中。相反,请执行try/finally
阻止并在Task.Run(() => producer.Dispose);
部分中调用finally
等。假设它们从不抛出异常,您将不需要等待Dispose
调用,但您可能应该进行单元测试。如果值得等待成功记录,那么值得等待处理调用。目标是能够并行执行大量这些ProduceMessage
调用(然后将它们作为批处理等待)。
您的Dispose
调用有可能正在执行磁盘或套接字刷新。您可能希望在关闭方案中等待它们。另一个选择是在Produce
调用中执行套接字刷新。这样你的成功记录会更加真实。
答案 1 :(得分:0)
如果您不希望Dispose
出现在调用者线程中,只需继续执行即可。唯一令人讨厌的部分是确保在producer.Topic(_kafkaOptions.Topic, topicConfig)
抛出异常时处理主题。
private async Task<bool> DoProduce(Topic topic, object someObject)
{
try
{
var report = await topic.Produce(someObject);
_logger.LogDebug("Producer Succeed");
return true;
}
catch (Exception ex)
{
HandleError(ex);
return false;
}
}
public Task<bool> ProduceAsync(object someObject)
{
var producer = new Producer(_kafkaOptions.Uri);
Topic topic = null;
try
{
topic = producer.Topic(_kafkaOptions.Topic, topicConfig);
}
finally
{
producer.Dispose();
}
var task = DoProduce(topic, someObject);
task.ContinueWith(t =>
{
topic.Dispose();
producer.Dispose();
}, TaskScheduler.Default);
return task;
}
答案 2 :(得分:-1)
如果你想要的是控制资源的处理,我觉得你应该把资源注入到方法中。
这将负责[创建它们]并将它们从方法中移除并允许它及时完成。然后,您可以决定如何单独销毁资源。