【问题标题】:C# Async Await on a Prism messagePrism 消息上的 C# 异步等待
【发布时间】:2026-01-17 18:45:01
【问题描述】:

是否可以等待来自事件聚合器(例如 prism)的回调?

    MessageManager.Subscribe("Reply", this.GetType().Name, Myfunc);

    private void Myfunc(object obj)
    {

    }

    public async void MyFunc2()
    {
        MessageManager.Publish("Request", xxx);

        await [Message Reply]
    }

在 lambda 中有一个丑陋的订阅方法,然后是取消订阅,但这不是很漂亮。

有更好的方法吗?

编辑:

这是我目前的解决方案:

    private SemaphoreSlim dataReady = new SemaphoreSlim(0, 1);
    MeasurementDataSet lastDataSet;

    public Calibrator(IMessageManager msgMgr)
    {
        MessageManager = msgMgr;

        MessageManager.Subscribe("NewMeasurementData", this.GetType().Name, OnMeasurementData);
    }

    private void OnMeasurementData(object obj)
    {
        lastDataSet = (MeasurementDataSet) obj;
        dataReady.Release();
    }

    public async void Calibrate(IParameterCache prmCache, Action<string> updateText)
    {

        MessageManager.Publish("InitiateMeasurement", "CAL ");
        await dataReady.WaitAsync();

        // do stuff             

        MessageManager.Publish("InitiateMeasurement", "CAL ");
        await dataReady.WaitAsync();
        // do stuff  
        MessageManager.Publish("InitiateMeasurement", "CAL ");
        await dataReady.WaitAsync();
        // do stuff  

    }

【问题讨论】:

  • Prism 几乎不是“消息总线”
  • 事件聚合器
  • await [Message Reply] 是什么意思?是在等待MyFunc 中发生的事情吗?
  • async-await 可能不是这里的最佳选择。它从不用于事件流。
  • 问题是它在后台控制一台硬件机器,并且必须经过特定的过程,因此使用await async比到处都有回调要容易得多。 @PauloMorgado

标签: c# callback async-await messaging


【解决方案1】:

您可以使用TaskCompletionSource&lt;T&gt; 来等待事件

public partial class MainWindow : Window
{
    IEventAggregator _eventAggregator;
    public MainWindow()
    {
        InitializeComponent();

        _eventAggregator = new EventAggregator();
        _eventAggregator.GetEvent<PubSubEvent<Request>>().Subscribe( payload =>
        {
            Thread.Sleep( 1000 ); // only fake work
            _eventAggregator.GetEvent<PubSubEvent<Response>>().Publish( new Response() );
        }, ThreadOption.BackgroundThread );
    }

    private async void Button_Click( object sender, RoutedEventArgs e )
    {
        ( (Button)sender ).IsEnabled = false;
        try
        {
            var tcs = new TaskCompletionSource<Response>();

            using ( var token = _eventAggregator.GetEvent<PubSubEvent<Response>>().Subscribe( payload =>
            {
                tcs.TrySetResult( payload );
            }, ThreadOption.BackgroundThread ) )
            {
                _eventAggregator.GetEvent<PubSubEvent<Request>>().Publish( new Request() );
                await tcs.Task;
            }
        }
        finally
        {
            ( (Button)sender ).IsEnabled = true;
        }
    }
}

public class Request
{

}

public class Response
{

}

【讨论】: