Windows RSS Platform Preview

曾经翻译过Longhorn中的RSS,那是Microsoft正式在Longhorn中加入RSS支持的白皮书。大概2个星期前吧,看到了Microsoft RSS Team Blog上面提到的Screen Saver的例子,才发现随着IE7 Beta2的发布,已经可以看到这个RSS Platform了。

大概看了一下整个文档,然后用C#编了个简单的小程序试了试,还不错,API还算合理好用,这下Desktop平台的对RSS支持变得非常容易了。

Windows RSS Platform的Online Reference在这里

  • Subscribe to new feeds, and enumerate existing subscriptions.
  • Easily access properties of feeds (channels), feed items, and enclosures.
  • Manage and organize feeds into folders.
  • Listen for and respond to feed and feed folder events.
  • Check the status of the background Feed Download Engine, or modify settings.
  • Normalize the Extensible Markup Language (XML) source of a feed.

这是Windows RSS Platform的对象体系图:

Windows RSS Platform Object Model

整个类体系的Top Class是FeedsManager,顺便说一句,XXManager一般都是各种类体系结构中的Top Class,是整个API的入口。比如Eclipse平台的Platform,比如Adapter体系的AdapterManager,比如Plugin体系中的PluginManager。

具体细节就不多说了,举几个简单的例子:(为了简单,我用C#试的,C++访问的话,就是访问COM接口,也很简单)

1) 同步RSS

  1. Feeds.IFeedsManager fs = new Feeds.FeedsManagerClass();
  2. fs.BackgroundSync(Feeds.FEEDS_BACKGROUNDSYNC_ACTION.FBSA_RUNNOW);

2) 订阅Feed Event

  1. Feeds.IFeedFolderEvents_Event e = (Feeds.IFeedFolderEvents_Event)folder.GetWatcher(Feeds.FEEDS_EVENTS_SCOPE.FES_ALL, Feeds.FEEDS_EVENTS_MASK.FEM_FEEDEVENTS);
  2. e.FeedAdded += new Feeds.IFeedFolderEvents_FeedAddedEventHandler(FeedAdded)
  3.  
  4. private static void FeedAdded(string path) {     
  5.     System.Diagnostics.Debug.Print(path);
  6. }

显然,Delegate的典型用法,如果用C++,当然就是使用IConnectionPoint来把回调函数加入到Feeds COM Object中的Notifier List。

3) 得到系统当前Feed列表(包括Feed Item Count)

  1. foreach (Feeds.IFeed feed in CommonFeedListUtils.CommonFeedList(folder))
  2. {
  3.     System.Diagnostics.Debug.Print("Found feed {0} with {1} items.",feed.name, ((Feeds.IFeedsEnum)feed.Items).Count);
  4.     try
  5.     {
  6.     }
  7.     catch (System.Runtime.InteropServices.COMException ex)
  8.     {
  9.         System.Diagnostics.Debug.Print("Failed to get RSS feed '{0}' from API; skipping feed. Error: {1} ", feed.name, ex.ToString());
  10.         // Ignore exception, meaning ignore this feed and continue with next feed.
  11.     }
  12. }
  13.    
  14. public static IEnumerable CommonFeedList(IFeedFolder folder) {     
  15.     Queue queue = new Queue();
  16.     queue.Enqueue(folder);
  17.     while (queue.Count > 0) {
  18.         IFeedFolder currentFolder = queue.Dequeue();
  19.         foreach (IFeedFolder subfolder in (IFeedsEnum)currentFolder.Subfolders)
  20.             queue.Enqueue(subfolder);
  21.            
  22.         foreach (IFeed feed in (IFeedsEnum)currentFolder.Feeds) {
  23.             System.Windows.Forms.Application.DoEvents();
  24.             yield return feed;
  25.         }     
  26.     }
  27. }

这段代码是从Screen Saver的例子中拿来的,惭愧的是,看了这段代码,我才知道C#中也有yield :(。再顺便插一句,特意查了一下C# Language Specification,yield是C# 2.0中新增的Feature,C#给出的yield的推荐实现(应该也是Microsoft的实现)是由编译器生成一个enumerator类,一个State Machine,正是这个State实现了yield。

4) 新增Feed或者Feed Folder

  1. folder.CreateFeed("Xerdoc Together", "http://feeds.feedburner.com/xerdoc");
  2. folder.CreateSubfolder("Elites");

基本上就是这样,Feed的管理将变的非常简单。不知道这个Platform对离线阅读器会有什么影响,不可否认的是,它很大程度降低了RSS开发的门槛,也使你可以更加将精力专注到逻辑和功能上。

Update:回答Winters的问题

其实看看CSharp2.0 Specification就明白了,其实很简单。它给出的例子是:

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. class Stack<T>: IEnumerable<T>
  5. {
  6.     T[] items;
  7.     int count;
  8.     public void Push(T item) {
  9.         if (items == null) {
  10.             items = new T[4];
  11.         }
  12.         else if (items.Length == count) {
  13.             T[] newItems = new T[count * 2];
  14.             Array.Copy(items, 0, newItems, 0, count);
  15.             items = newItems;
  16.         }
  17.         items[count++] = item;
  18.     }
  19.     public T Pop() {
  20.         T result = items[--count];
  21.         items[count] = default(T);
  22.         return result;
  23.     }
  24.     public IEnumerator<T> GetEnumerator() {
  25.         for (int i = count - 1; i >= 0; --i) yield return items[i];
  26.     }
  27. }

编译的时候生成一个enumerator辅助类:

  1. class Stack<T>: IEnumerable<T>
  2. {
  3.     ...
  4.     public IEnumerator<T> GetEnumerator() {
  5.         return new __Enumerator1(this);
  6.     }
  7.     class __Enumerator1: IEnumerator<T>, IEnumerator
  8.     {
  9.         int __state;
  10.         T __current;
  11.         Stack<T> __this;
  12.         int i;
  13.         public __Enumerator1(Stack<T> __this) {
  14.             this.__this = __this;
  15.         }
  16.         public T Current {
  17.             get { return __current; }
  18.         }
  19.         object IEnumerator.Current {
  20.             get { return __current; }
  21.         }
  22.         public bool MoveNext() {
  23.             switch (__state) {
  24.                 case 1: goto __state1;
  25.                 case 2: goto __state2;
  26.             }
  27.             i = __this.count - 1;
  28.         __loop:
  29.             if (i < 0) goto __state2;
  30.             __current = __this.items[i];
  31.             __state = 1;
  32.             return true;
  33.         __state1:
  34.             --i;
  35.             goto __loop;
  36.         __state2:
  37.             __state = 2;
  38.             return false;
  39.         }
  40.         public void Dispose() {
  41.             __state = 2;
  42.         }
  43.         void IEnumerator.Reset() {
  44.             throw new NotSupportedException();
  45.         }
  46.     }
  47. }

In the preceding translation, the code in the iterator block is turned into a state machine and placed in the MoveNext method of the enumerator class. Furthermore, the local variable i is turned into a field in the enumerator object so it can continue to exist across invocations of MoveNext.

Popularity: 66%

Related entries:

  • No Related Posts

3 Responses to “Windows RSS Platform Preview”

  1. Winters Mi Says:

    没太看明白这个yield,还有state machine实现yield的机制
    有时间的话,能不能详细介绍一下,呵呵

  2. Meng Yan Says:

    我Update在上面了,呵呵。

  3. tz Says:

    最近要搞一个在linux上的RSS Reader,现在还不知如何下手,不知是用java好呢还是用c++还是用php

    能给点意见吗 并且能讲讲用c++怎样实现上边的功能

    谢谢啦

Leave a comment

(required)

(required)


Information for comment users
Line and paragraph breaks are implemented automatically. Your e-mail address is never displayed. Please consider what you're posting.

Use the buttons below to customise your comment.


RSS feed for comments on this post | TrackBack URI

 

Creative Commons License
This work is licensed under a Creative Commons License.

没有什么能够阻挡,你对未来的向往