65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 UIAPB 在 Web 应用程序中实现多任务(子窗口)功能

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.42/5 (10投票s)

2006年8月17日

Ms-PL

2分钟阅读

viewsIcon

31333

downloadIcon

263

本文描述了一种使用用户界面流程应用程序块 2.0 实现共享会话、多任务功能的解决方案。

引言

我看到许多人在论坛上抱怨使用用户界面流程应用程序块 (UIPAB) 时,单用户运行多任务功能的问题。尤其是在Web应用程序中(事实上,每个问题都提到了Web应用程序)。UIPAB 的官方文档建议实现 `ITask` 接口,并明确处理单用户同时运行多个任务的情况(尽管没有提供代码示例)。本文通过对 UIPAB 代码进行一些小的更改来解决这个问题。请注意,UIPAB 可从 Microsoft 的模式与实践网站下载。

隐藏的问题

使用 UIPAB 实现多个窗口(包含多个任务)场景存在一个基本问题。

UIPAB 将 `ActiveTaskID` 存储在会话变量中,该变量由同一台计算机上的所有浏览器实例共享。因此,UIPAB 本身一次只能激活一个任务(它保存所有任务的状态,但一次只保持一个任务处于活动状态)。`ActiveTaskID` 用于 `WebFormView` 类的 `Load` 事件处理程序中,以检索任务的状态。

解决方案

这种行为导致 UIPAB 只能激活一个任务。我们需要一种方法来在一个实例中激活多个任务。这使我们得出一个明显的结论:我们不能将 `ActiveTaskID` 存储在会话中。我们需要将其与页面一起存储。我考虑将其存储在页面的 ViewState 中。但是,由于所有导航都通过 `Response.Redirect` 进行,因此无法将 `TaskID` 存储在 ViewState 中。然后,我决定将 taskID 放入页面请求的查询字符串中。我必须对 Microsoft 提供的代码进行两处更改才能实现这一点。

  • 对 `WebFormView` 类的更改:用以下内容替换默认的 `GetSessionMoniker` 方法
  • private SessionMoniker GetSessionMoniker()
    {
        SessionMoniker sessionMoniker = null;
            try
            {
                sessionMoniker = SessionMoniker.GetFromSession(new Guid(Request.QueryString["taskId"]));
            }
            catch(Exception ex)
            {
                throw new UIPException(Resource.Exceptions.RES_ExceptionTaskNotFound);
            }
        return sessionMoniker;
    }
  • `WebFormViewManager` 类:用以下代码替换 `ActivateView` 和 `RedirectToNextView` 方法
  • public void ActivateView( string previousView, Guid taskId, string navGraph, string view )
    {
        //  create a session moniker
        SessionMoniker sessionMoniker = new SessionMoniker( navGraph, view, taskId);
        // store the moniker into the session, so the next view can get the task information
        sessionMoniker.StoreInSession();
                
        ViewSettings viewSettings = UIPConfiguration.Config.GetViewSettingsFromName( view ); 
        if( viewSettings == null )
            throw new UIPException(
                Resource.ResourceManager.FormatMessage(
                    Resource.Exceptions.RES_ExceptionViewConfigNotFound, view ) );
                
        HttpContext.Current.Session[WebFormView.CurrentTaskKey] = taskId.ToString();
        RedirectToNextView(previousView, viewSettings, taskId);
    }
    
    private void RedirectToNextView(string previousView, ViewSettings viewSettings, Guid taskId)
    {
        try
        {
            if (previousView == null)
                HttpContext.Current.Response.Redirect(
                    HttpContext.Current.Request.ApplicationPath + 
                    "/" + viewSettings.Type + 
                    "?taskID=" + 
                    taskId.ToString(), 
                    true);
            else
                HttpContext.Current.Response.Redirect(
                    HttpContext.Current.Request.ApplicationPath + 
                    "/" + viewSettings.Type 
                    + "?taskID=" + 
                    taskId.ToString(), 
                    false);
        }
        catch (System.Threading.ThreadAbortException) { }
    }

使用代码

按原样使用代码。您可以通过下载修改后的 UIP 代码直接开始使用它。或者,您可以自己对从 Microsoft 网站下载的 UIPAB 代码进行更改。

注意

对 UIPAB 的修改完全由我本人完成,Microsoft 与此无关。如果由于使用此代码(特别是修改的功能)而遇到任何问题,Microsoft 对此概不负责。商业用途的代码应在彻底测试后才能使用。对于因使用所包含的代码而产生的任何错误行为,我不承担任何责任。

本文使用 UIPAB 2.0。相同的更改也可以应用于 UIPAB 1.x,但我个人没有这样做。

© . All rights reserved.