【问题标题】:Dependencies being disposed when using trying to run an asynchronous task in WCF with Autofac使用 Autofac 尝试在 WCF 中运行异步任务时处理依赖项
【发布时间】:2012-11-30 23:06:19
【问题描述】:

我目前正在使用 WCF 服务,该服务应该生成一个新任务以在服务器上异步运行(需要进行数据库查询等)。有可能(并且很可能)在新任务完成保证客户端关闭之前将响应发送回客户端。此时,在创建任务期间可用的依赖项将不再可用。为了完成任务,我仍然需要一些依赖项。

我想如何确保新任务所需的依赖项仍然存在?

我包含了一些非常简单的代码来给出一个基本的例子。

public string SubmitData(
            User user, Request request)
        {
            History history = m_history.CreateRequest(user);

            //New task which will do an import of data into the DB.
           Task.Factory.StartNew( () => 
               Import( user, request, history ) ); 

           /*Return some sort of response back to user so they're not waiting for 
           *the long process to complete           
           */
           return "Response";
        }

        private void Import(
            User user,
            Request request,
            History history)
        {
            var response = Import(
                user, request, history);
            m_history.Save(history, response );
        }

【问题讨论】:

  • 客户会对响应做些什么?
  • 是的。他们会从响应中获取一些数据,以便他们可以稍后发送请求以查看导入结果。
  • 示例代码无效,并不能真正说明问题。问题留给读者很多,即您没有提及 autofac 的确定性处理,并且您必须设置范围和生命周期,以便在此调用后释放相关依赖项。
  • @vossad1:不过,我认为这可能是 Autofac 新手在了解如何使用各种关系类型操纵分辨率范围和生命周期之前查看处置问题的方式。连同你的回答,这个问题当然是值得的。确实,主要是因为答案,但仍然如此。

标签: c# wcf asynchronous autofac .net-4.5


【解决方案1】:

您需要自己负责处理依赖项。由于您使用的是autofac,因此您最简单的解决方案可能是使用Owned<T>

查看文档:Owned Instances

这里大概是我会考虑你的代码来利用Owned<T>,虽然有很多可能性:

    private Func<Owned<Importer>> importerFactory = //Constructor Injected.

    public string SubmitData(
        User user, Request request)
    {
        History history = m_history.CreateRequest(user);

        //New task which will do an import of data into the DB.
        Task.Factory.StartNew(() =>
            {
                using (var importer = importerFactory())
                {
                    importer.Value.Import(user, request, history);
                }
            });

        /*Return some sort of response back to user so they're not waiting for 
       *the long process to complete           
       */
        return "Response";
    }

    public class Importer
    {
        //m_history ...

        public void Import(
            User user,
            Request request,
            History history)
        {
            var response = Import(user, request, history);
            m_history.Save(history, response);
        }
    }

从你的问题来看。您可能会从有关 Autofac、生命周期和确定性处置的额外阅读中受益。

Instance Scope

Lifetime Primer

Deterministic Disposal

一旦您更深入地了解 autofac 的工作原理,您就会意识到您的问题实际上更普遍。即,如何确保正确处理任务中使用的共享对象。在我上面的代码中,我通过不共享对象和处理任务来解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多