0

如何让后台代理执行等待所有ImageOpened()事件被触发(在本例中为 3 个),以便使用自定义图像更新辅助活动磁贴?

编辑1:

在我正在调用我自己的创建磁贴数据函数的OnInvoke()方法中,该函数在共享库中实现,当我尝试为所有实时磁贴模板(即小、中和宽)创建自定义图像时,该函数又订阅 3 个事件。ScheduledAgentImageOpened()

由于这些是异步事件,我无法检查所有事件是否已成功完成,以便我可以调用NotifyComplete()以通知后台代理其工作现已完成。因此,有时磁贴会更新,而大多数情况下不会。此外,每次启动应用程序时,我都使用相同的功能来更新动态磁贴,因此它的实现没有问题。GC.Collect()我还尝试通过处理位图并强制调用来处理 ScheduledAgent 的所有内存限制。

请以任何可能的方式帮助解决此问题。

4

1 回答 1

1

添加一个允许您创建自定义事件的新类 -

public class SaveImageCompleteEventArgs : EventArgs
{
    public bool Success { get; set; }
    public Exception Exception { get; set; }
    public string ImageFileName { get; set; }

    public SaveImageCompleteEventArgs(bool success, string fileName)
    {
        Success = success;
        ImageFileName = fileName;
    }
}

初始化您要更新自定义活动磁贴的文件中的事件和所需变量 -

public static int countTile = 3;
public event EventHandler<SaveImageCompleteEventArgs> SaveMediumImageComplete;
public event EventHandler<SaveImageCompleteEventArgs> SaveWideImageComplete;
public event EventHandler<SaveImageCompleteEventArgs> SaveSmallImageComplete;
public event EventHandler<SaveImageCompleteEventArgs> SaveAllImagesComplete;

在所有图块的事件处理程序中触发完成事件ImageOpened()并检查是否SaveAllImagesComplete需要触发该事件 -

public void OnBackgroundBmpOpenedMedium(object sender, RoutedEventArgs e)
{
    if (SaveMediumImageComplete != null)
    {
        countTile -= 1;
        CheckIfAllImagesOpened();
        SaveMediumImageComplete(this, new SaveImageCompleteEventArgs(true, mediumTileImageUriIronMan));
    }
}

private void CheckIfAllImagesOpened()
{
    if (countTile == 0)
    {
        if (SaveAllImagesComplete != null)
        {
            var args1 = new SaveImageCompleteEventArgs(true, "");
            SaveAllImagesComplete(this, args1);
        }
    }
}

在 ScheduledAgent 文件中 -

public static ManualResetEvent evt;
public bool IsPaused { get { return !evt.WaitOne(0); } }

在 OnInvoke() 函数中 -

evt = new ManualResetEvent(false);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
    //Initialize secondary tile here

    if (secondaryTile != null)
    {
        /* 
        obj is a object of a helper file that contains all the  
        functions responsible for updating the custom live tile

        Call the function that is responsible for initializing all the  
        tile image bitmpas and that subscribes to the ImageOpened events 
        */

        obj.SaveMediumImageComplete += async (s, args) =>
        {
            if (!IsPaused)
                evt.Set();
        };
        obj.SaveWideImageComplete += async (s, args) =>
        {
            if (!IsPaused)
                evt.Set();
        };
        obj.SaveSmallImageComplete += async (s, args) =>
        {
            if (!IsPaused)
                evt.Set();
        };
        obj.SaveAllImagesComplete += async (s, args) =>
        {
            try
            {
                if (args.Success)
                    obj.UpdateTileIcon();
            }
            catch (Exception) { }
            finally
            {
                if (!IsPaused)
                    evt.Set();
            }
        };
    }
});
evt.WaitOne();
NotifyComplete();
于 2015-03-22T10:16:47.157 回答