Caliburn.Micro EventAggregator.PublishOnUIThreadAsync“ tasks参数包含一个空值参数名称:tasks”

问题描述

我正在尝试使用EventAggregator进行跨VM通信。

在我的Childviewmodel中,我做类似的事情:

public async void ThisMethodisCalledByUI()
{
    // ShowMessageEvent is a simple class with with only 1 string property and a MessageDialogResult enum
    ShowMessageEvent msg = new ShowMessageEvent("This is the message from ChildVM");

    // doing this works,but MessageDialogResult will be false below since no await happens
    //_eventAggregator.PublishOnUIThreadAsync(msg);

    // doing this triggers exception
    // however msg.DialogResult is already Affirmative by the time 
    // the exception is thrown,so it's almost as intended here
    await _eventAggregator.PublishOnUIThreadAsync(msg);

    // expected: Affirmative
    Debug.WriteLine(msg.DialogResult);

}

但是,由于我要使用MessageDialogResult,因此需要等待。 在Mainviewmodel中:

public class Mainviewmodel : Conductor<IScreen>.Collection.OneActive,IHandle<object>
{
    private readonly IEventAggregator _eventAggregator;

    public Mainviewmodel()
    {
        _eventAggregator = new EventAggregator();
        _events.SubscribeOnPublishedThread(this);
    }

    public async Task HandleAsync(object message,CancellationToken cancellationToken)
    {
        if (message is ShowMessageEvent msg)
        {
            // Simulating work,show dialog,etc.
            await Task.Delay(500);
            // Implementation irrelevant,assume the dialog returns Affirmative
            msg.DialogResult = await _dialogs.ShowMessageAsync(msg.Message);

        }
    }
}

因此,目标是通知Mainviewmodel显示对话框,然后等待并在Childviewmodel中检索对话框结果,然后再继续。是的,我可以直接从Childviewmodel调用该对话框作为一种解决方法,但这不是重点,我想避免这种情况。

我的实现基本上已经按预期完成了所有工作,我唯一需要解决的就是抛出的异常。

有人知道我在做什么错吗?

编辑

我实际上可以使它像这样工作:

public async void ThisMethodisCalledByUI()
{
    // ShowMessageEvent is a simple class with with only 1 string property and a MessageDialogResult enum
    ShowMessageEvent msg = new ShowMessageEvent("This is the message from ChildVM");

    try
    {
        await _eventAggregator.PublishOnUIThreadAsync(msg);
    }
    // suppress the problematic exception
    catch (ArgumentException e)
    {
        Console.WriteLine(e);
    }

    // works as expected: Affirmative
    Debug.WriteLine(msg.DialogResult);

}

尽管这是可行的,但我希望设计不需要抑制异常...

解决方法

到目前为止,我最终完成了自己的扩展程序实现

/// <summary>
/// EventAggregatorExtensions
/// </summary>
public static class EventAggregatorExtensions
{
    /// <summary>
    /// Publishes a message to the UI thread 
    /// </summary>
    /// <param name="eventAggregator"></param>
    /// <param name="message"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public static async Task PublishOnUIThreadAsyncCustom(this IEventAggregator eventAggregator,object message,CancellationToken cancellationToken)
    {
        try
        {
            await eventAggregator.PublishOnUIThreadAsync(message,cancellationToken);
        }
        // Suppress a specific exception that is always caused when above line is awaited
        catch (ArgumentException e)
        {
            if (!e.Message.Contains("The tasks argument included a null value.") | !e.ParamName.Equals("tasks"))
            {
                throw;
            }
        }
    }

    /// <summary>
    /// Publishes a message to the UI thread 
    /// </summary>
    /// <param name="eventAggregator"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    public static async Task PublishOnUIThreadAsyncCustom(this IEventAggregator eventAggregator,object message)
    {
        await PublishOnUIThreadAsyncCustom(eventAggregator,message,CancellationToken.None);
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...