5

オブジェクトの破棄に関するStefan Gossner の投稿と、 Cross method dispose patternsに関するこの質問を読んだ後、誤って SPWeb を再度開いてしまったことがわかりました。Stefan Gossner の投稿で、子オブジェクトの処理が終了したら SPWeb を破棄する必要があると述べていることを知っています。ただし、Microsoft のドキュメントには、SPListItemCollection オブジェクトのキャッシュについて言及されています。次のコードは正しいですか? 返された SPListItemCollection は SPWeb オブジェクトを再度開きますか? 確実に伝える方法はありますか?

// is this correct????
private SPListItemCollection GetListItems()
{
    SPListItemCollection items = null;
    try
    {
        using (SPSite site = new SPSite(GetListSiteUrl()))
        {
            using (SPWeb web = site.OpenWeb())
            {
                // retrieve the list
                SPList list = web.Lists[_ListName];

                // more code to create the query...
                items = list.GetItems(query);
            }
        }
    }
    catch (Exception e)
    {
        // log error
    }
    return items;
}

編集 09/09/09

主にStefan Grossner の投稿のこの部分を参照しています。

このオブジェクトの子オブジェクトに最後にアクセスした後、SPWeb または SPSite オブジェクトを破棄する必要があります。

彼が言っていることは、以前に取得したSPWebを破棄した後にSPListItemCollectionを使用すると、SPWebが自動的に再度開かれるということだと思います。

4

3 に答える 3

4

Stefan に直接尋ねたところ、SPListItemCollection を破棄した後で実際に SPWeb を再度開くことができることがわかりました。これは、上記のコードが正しくないことを意味し、SPListItemCollection を使用した後にのみ SPWeb を破棄できます。

更新: SPListItemCollection を別のものに変換し、代わりにそれを返すことをお勧めします。

private DataTable GetListItems()
{
    DataTable table = null;
    try
    {
        SPListItemCollection items = null;
        using (SPSite site = new SPSite(GetListSiteUrl()))
        {
            using (SPWeb web = site.OpenWeb())
            {
                // retrieve the list
                SPList list = web.Lists[_ListName];

                // more code to create the query...
                items = list.GetItems(query);

                // convert to a regular DataTable
                table = items.GetDataTable();
            }
        }
    }
    catch (Exception e)
    {
        // log error
    }
    return table;
}
于 2009-09-09T15:23:06.833 に答える
1

私が知る限り、答えはノーですが、次のようなコードを書いたでしょう

private void FetchItems(Action<SPListItemCollection> action)
{
   using(...)
   {
       var items = list.GetItems(query);
       action(items);
   }
}

これにより、このメソッドを呼び出すには、SPListItemCollection を使用するメソッド (デリゲート) を送信する必要があります。次に例を示します。

FetchItems( items => ....) または FetchItems( DoStuffWithItems(SPListItemCollection) )

于 2009-09-08T17:11:34.260 に答える
0

SPListItemCollection を使い始めたときに、同じスコープで SPWeb が必要かどうかについて話しているのであれば、答えはノーだと思います。

たとえば、私は定期的に次のことを行います。

    private IEnumerable<SPListItem> AllItems;

    public void GetItems()
    {
        var results = SPContext.Current.Web.Lists[ListName].Items.Cast<SPListItem>();
        this.AllItems = results;
    }

そして、私は AllItems をいたるところで使用していますが、うまく機能します。

ご参考までに、キャストが完了しているため、結果セットで Linq を使用できます。特に、データに対して複数のサブセレクトを実行している場合は、クエリをリストに送信するよりもはるかに高速です。

于 2009-09-08T22:48:23.207 に答える