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

通过实现 PageAsyncTask 在 MOSS 页面中实现多线程

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (4投票s)

2008年4月24日

CPOL

1分钟阅读

viewsIcon

40289

downloadIcon

176

使用PageAsyncTask实现Web Part并行渲染,代替RegisterWorkItem。

引言

目前,越来越多的公司开始迁移到SharePoint 2007。作为SharePoint应用程序的基础,Web Part需要更多关注,因为它们会根据业务或用户需求进行定制。让我们讨论一下如何将异步Web Part从SharePoint 2003升级到SharePoint 2007的一些问题。

背景

当开发者重新编译一个使用Microsoft.SharePoint.WebPartPages.WebPart.RegisterWorkItem实现多线程渲染的Web Part时,他们会发现一个警告:'Microsoft.SharePoint.WebPartPages.WebPart.RegisterWorkItemCallback(System.Threading.WaitCallback, object)' is obsolete: 'Use Page.RegisterAsyncTask instead.'

实现Page.RegisterAsyncTask很简单,就像MSDN所说的那样。挑战在于如何使其在SharePoint Web Part页面中工作…

首先,让我们过一下源代码

该项目包含三个类文件:Web Part类(包括如何实现WebPartMultiThread方法和设置超时消息),WebPartMultiThread定义类,以及WebPartMultiThread包类。

Web Part类

using System;
using System.Web;
using System.Web.UI;
using System.Threading;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;

public class WorkItemSample : 
       Microsoft.SharePoint.WebPartPages.WebPart
{
    string log = "";
    ManualResetEvent mre = new ManualResetEvent(false);

    bool threadTimeOut = false;
    WebPartMultiThread MultiThread;

    public WorkItemSample()
    {
    }
    protected override void OnPreRender(EventArgs e)
    {
        log += "before register: " + 
               DateTime.Now.ToLongTimeString() + "<BR>";
        MultiThread = new WebPartMultiThread(threadTimeOut, this.Page);
        MultiThread.RegisterWorkItemCallback(new WaitCallback(DoWork), null);
        //DoWork(null);
        log += "after register: " + 
               DateTime.Now.ToLongTimeString() + "<BR>";
    }
    protected override void RenderWebPart(HtmlTextWriter output)
    {
        if (MultiThread != null && MultiThread.ThreadTimeOut)
        {
            string TimeoutMessage = "Timed out";
            MultiThread.RenderWorkItemTimeout(output, TimeoutMessage);                
        }
        else
        {
            log += "RenderWebPart: " + 
                   DateTime.Now.ToLongTimeString() + "<BR>";
            output.Write(log);
        }           
    }

    // Sleep for 5 seconds to simulate doing work
    private void DoWork(object o)
    {
        log += "before DoWork: " + DateTime.Now.ToLongTimeString() + 
               this.Title + "<BR>";
        Thread.Sleep(7000);
        log += "After DoWork: " + DateTime.Now.ToLongTimeString() + 
               this.Title + "<BR>";
        mre.Set();
    }
}

OnPreRender期间,我们创建一个新的WebPartMultiThread类实例,并为其提供一个threadTimeout来决定何时超时。然后,我们调用RenderWorkItemTimeout(此方法不是Microsoft.Sharepoint.WebPartPage.WebPart.RenderWorkItemTimeOut)来开始并行渲染Web Part(假设每个Web Part消耗5秒),以实现性能。在RenderWebPart期间,我们将根据是否超时来渲染不同的内容。

WebPartMultiThread定义类

using System;
using System.Web;
using System.Web.UI;
using System.Threading;
using System.Xml.Serialization;
public class WebPartMultiThread
{
    private bool _threadtimeout;
    private Page _page;

    public bool ThreadTimeOut
    {
        set
        {
            _threadtimeout = value;
        }
        get
        {
            return _threadtimeout;
        }
    }

    public System.Web.UI.Page myPage
    {
        set
        {
            _page = value;
        }
        get
        {
            return _page;
        }
    }
    public WebPartMultiThread(bool pThreadTimeOut, Page pPage)
    {
        ThreadTimeOut = pThreadTimeOut;
        myPage = pPage;
    }

    public bool RegisterWorkItemCallback(WaitCallback beginCallBack, object state)
    {
        if (!this.ThreadTimeOut)
        {
            WebPartMultiThreadPacket pa = new WebPartMultiThreadPacket();
            pa.state = state;
            pa.beginCallBack = beginCallBack;
            PageAsyncTask task = new PageAsyncTask(new BeginEventHandler(
                                 this.OnTaskBeginWithWaitCallback), 
                                 new EndEventHandler(this.OnTaskEnd), 
                                 new EndEventHandler(this.OnTaskTimeout), pa, true);

            if (this.myPage != null)
            {
                this.myPage.RegisterAsyncTask(task);
            }
        }
        else
            return false;
        return true;
    }
    private IAsyncResult OnTaskBeginWithWaitCallback(object sender, 
                         EventArgs e, AsyncCallback cb, object o)
    {
        return ((WebPartMultiThreadPacket)o).beginCallBack.BeginInvoke(
                ((WebPartMultiThreadPacket)o).state, cb, null);
    }
    private void OnTaskEnd(IAsyncResult ar)
    {
    }
    private void OnTaskTimeout(IAsyncResult ar)
    {
        this.ThreadTimeOut = true;
    }
    public void RenderWorkItemTimeout(HtmlTextWriter output, string outputMessage)
    {
        output.Write(outputMessage);
    }
}

如何实现OnTaskBeginWithWaitCallback()是该项目的重要组成部分。它需要一个WebPartMultiThreadPacket实例。

WebPartMultiThread包类

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Xml.Serialization;
public class WebPartMultiThreadPacket
{
    public WaitCallback beginCallBack;
    public object state;

    public WebPartMultiThreadPacket()
    {
    }
}

当您运行此页面时,您会看到类似以下截图的内容

历史

这是第一个版本。

© . All rights reserved.