Cleaned up item filtering and some other small todos.

This commit is contained in:
Patrick Simpson 2017-02-15 10:38:57 +01:00
parent 9e0603e22f
commit 10d2bd4d65
8 changed files with 94 additions and 41 deletions

View File

@ -321,24 +321,20 @@ namespace Acacia.Features.GAB
{
using (IFolder root = store.GetRootFolder())
{
foreach (IFolder folder in root.GetSubFolders<IFolder>())
foreach (IFolder folder in root.GetSubFolders<IFolder>().DisposeEnum())
{
// TODO: let enumerator handle this
using (folder)
try
{
try
if (IsGABContactsFolder(folder))
{
if (IsGABContactsFolder(folder))
{
Logger.Instance.Debug(this, "FullResync: Deleting contacts folder: {0}", folder.Name);
folder.Delete();
}
}
catch (System.Exception e)
{
Logger.Instance.Error(this, "FullResync: Exception deleting contacts folder: {0}", e);
Logger.Instance.Debug(this, "FullResync: Deleting contacts folder: {0}", folder.Name);
folder.Delete();
}
}
catch (System.Exception e)
{
Logger.Instance.Error(this, "FullResync: Exception deleting contacts folder: {0}", e);
}
}
}
}

View File

@ -200,24 +200,21 @@ namespace Acacia.Features.GAB
return;
// Process the messages
foreach (IItem item in Folder.Items)
foreach (IZPushItem item in Folder.Items.Typed<IZPushItem>())
{
// TODO: make type-checking iterator?
if (item is IZPushItem)
// Store the entry id to fetch again later, the item will be disposed
string entryId = item.EntryID;
Logger.Instance.Trace(this, "Checking chunk: {0}", item.Subject);
if (_feature.ProcessItems2)
{
string entryId = item.EntryID;
Logger.Instance.Trace(this, "Checking chunk: {0}", item.Subject);
if (_feature.ProcessItems2)
Tasks.Task(_feature, "ProcessChunk", () =>
{
Tasks.Task(_feature, "ProcessChunk", () =>
using (IItem item2 = Folder.GetItemById(entryId))
{
using (IItem item2 = Folder.GetItemById(entryId))
{
if (item2 != null)
ProcessMessage((IZPushItem)item2);
}
});
}
if (item2 != null)
ProcessMessage((IZPushItem)item2);
}
});
}
}
}

View File

@ -25,6 +25,12 @@ namespace Acacia.Stubs
/// <returns>The current collection, which will be sorted</returns>
IItems Sort(string field, bool descending);
/// <summary>
/// Filters the items for a specific type.
/// </summary>
/// <returns>An enumerable for items of the specified type.</returns>
IEnumerable<T> Typed<T>() where T : IItem;
/// <summary>
/// Returns an events subscribption object.
/// </summary>

View File

@ -46,7 +46,7 @@ namespace Acacia.Stubs.OutlookWrappers
public void Clear()
{
foreach(dynamic item in _item.Items.RawEnum())
foreach(dynamic item in _item.Items.ComEnum())
{
item.Delete();
}

View File

@ -207,7 +207,7 @@ namespace Acacia.Stubs.OutlookWrappers
where FolderType : IFolder
{
// Don't release the items, the wrapper manages them
foreach (NSOutlook.Folder folder in _item.Folders.RawEnum(false))
foreach (NSOutlook.Folder folder in _item.Folders.ComEnum(false))
{
yield return folder.Wrap<FolderType>();
};
@ -228,7 +228,7 @@ namespace Acacia.Stubs.OutlookWrappers
// to prevent exceptions in the log.
// Don't release the items in RawEnum, they are release manually or handed to WrapFolders.
NSOutlook.Folder sub = null;
foreach(NSOutlook.Folder folder in _item.Folders.RawEnum(false))
foreach(NSOutlook.Folder folder in _item.Folders.ComEnum(false))
{
if (folder.Name == name)
{

View File

@ -22,7 +22,7 @@ namespace Acacia.Stubs.OutlookWrappers
public IEnumerator<IFolder> GetEnumerator()
{
// Don't release the items, the wrapper manages them
foreach (NSOutlook.Folder folder in _folder.RawItem.Folders.RawEnum(false))
foreach (NSOutlook.Folder folder in _folder.RawItem.Folders.ComEnum(false))
{
yield return folder.Wrap<IFolder>();
};
@ -31,7 +31,7 @@ namespace Acacia.Stubs.OutlookWrappers
IEnumerator IEnumerable.GetEnumerator()
{
// Don't release the items, the wrapper manages them
foreach (NSOutlook.Folder folder in _folder.RawItem.Folders.RawEnum(false))
foreach (NSOutlook.Folder folder in _folder.RawItem.Folders.ComEnum(false))
{
yield return folder.Wrap<IFolder>();
};

View File

@ -13,6 +13,7 @@ namespace Acacia.Stubs.OutlookWrappers
{
// Managed by the caller, not released here
private readonly FolderWrapper _folder;
private string _field;
private bool _descending;
@ -28,6 +29,21 @@ namespace Acacia.Stubs.OutlookWrappers
return this;
}
public IEnumerable<T> Typed<T>() where T: IItem
{
foreach(IItem item in this)
{
if (typeof(T).IsInstanceOfType(item))
{
yield return (T)item;
}
else
{
item.Dispose();
}
}
}
private NSOutlook.Items GetItems()
{
return _folder.RawItem.Items;
@ -35,7 +51,7 @@ namespace Acacia.Stubs.OutlookWrappers
public IEnumerator<IItem> GetEnumerator()
{
return new ItemsEnumerator<IItem>(this, _field, _descending);
return new ItemsEnumerator<IItem>(this);
}
IEnumerator IEnumerable.GetEnumerator()
@ -51,13 +67,15 @@ namespace Acacia.Stubs.OutlookWrappers
private IEnumerator _enum;
private ItemType _last;
public ItemsEnumerator(ItemsWrapper items, string field, bool descending) : base(items.GetItems())
public ItemsEnumerator(ItemsWrapper items) : base(items.GetItems())
{
// TODO: can _items be released here already?
if (field != null)
// Apply any sort options
if (items._field != null)
{
this._item.Sort("[" + field + "]", descending);
this._item.Sort("[" + items._field + "]", items._descending);
}
// Get the enumerator
this._enum = _item.GetEnumerator();
}

View File

@ -45,7 +45,15 @@ namespace Acacia.Utils
return a.Equals(b);
}
public static IEnumerable<T> RawEnum<T>(this IEnumerable<T> source, bool releaseItems = true)
#region Enumeration helpers
/// <summary>
/// Extension for a Com enumeration. Disposes the enumerated object and - optionally - the returned elements.
/// </summary>
/// <param name="source">The object to be enumerated. This will be released.</param>
/// <param name="releaseElements">If true (the default), elements will also be released.</param>
/// <returns></returns>
public static IEnumerable<T> ComEnum<T>(this IEnumerable<T> source, bool releaseElements = true)
{
foreach (T item in source)
{
@ -55,14 +63,20 @@ namespace Acacia.Utils
}
finally
{
if (releaseItems)
if (releaseElements)
ComRelease.Release(item);
}
}
ComRelease.Release(source);
}
public static IEnumerable RawEnum(this IEnumerable source, bool releaseItems = true)
/// <summary>
/// Extension for a Com enumeration. Disposes the enumerated object and - optionally - the returned elements.
/// </summary>
/// <param name="source">The object to be enumerated. This will be released.</param>
/// <param name="releaseElements">If true (the default), elements will also be released.</param>
/// <returns></returns>
public static IEnumerable ComEnum(this IEnumerable source, bool releaseElements = true)
{
foreach (object item in source)
{
@ -72,13 +86,35 @@ namespace Acacia.Utils
}
finally
{
if (releaseItems)
if (releaseElements)
ComRelease.Release(item);
}
}
ComRelease.Release(source);
}
/// <summary>
/// Helper for enumeration that disposes the returned items. Note that source will not be disposed,
/// as that is normally done by foreach.
/// </summary>
public static IEnumerable<T> DisposeEnum<T>(this IEnumerable<T> source)
where T : IDisposable
{
foreach (T item in source)
{
try
{
yield return item;
}
finally
{
item.Dispose();
}
}
}
#endregion
public static void GarbageCollect()
{
for (int i = 0; i < 4; ++i)