0

我正在开发一个 XMPP 消息传递应用程序,并在用户成功登录时触发一个事件。订阅它的事件会关闭登录表单并打开主表单。简单的东西——除了我必须使用 SynchronizationContext 来访问登录表单的 Close() 方法。

这是它的工作原理:

private SynchronizationContext syncContext; //Global SynchronizationContext

在登录表单的构造函数内部

InitializeComponent();

//set to current after initialization
syncContext = SynchronizationContext.Current;

//subscribe to the event
EventAggregator.GetEvent<ContactListReadyEvent>().Subscribe(LoginResultHandler);

最后是触发 ContactListReadyEvent 时运行的函数

private void LoginResultHandler(ContactListReadyEventObject result)
{
    // send to UI thread
    syncContext.Send(new SendOrPostCallback(delegate
    {
        EventAggregator.GetEvent<ContactListReadyEvent>).Unsubscribe(LoginResultHandler);
        mainFrm.Show();
        mainFrm.Focus();

        this.Close();
    }), null);
}

这段代码都运行得很好……大多数时候。但每隔一段时间,登录表单就会冻结。

我设置了一些日志来找出在哪里,它进入LoginResultHandlersyncContext.Send. 我想知道这是因为我应该使用syncContext.Post,还是应该使用 aWindowsFormsSynchronizationContext而不是 a SynchronizationContext

我知道这不是需要处理的太多信息,其他一些可能有用的信息是在使用该 mainFrm 的其他区域中订阅了此事件 - 但是当登录表单冻结它时,因为它syncContext.send从不运行任何东西,就像它在运行之前一直在等待某件事发生。

任何帮助或提示将不胜感激。

4

1 回答 1

0

你不需要其他任何东西。在您的构造函数中的主表单中以及在初始化组件之前执行此操作。在您的登录表单中,您可以设置对话结果 = 确定,如果您按下确定或者他选择取消,您可以设置对话结果 = 取消。

frmLogin login = new frmLogin();
if(login.ShowDialog() == DialogResult.Cancel)
  this.Close();

InitializeComponent() //of your main form
于 2013-07-23T17:29:07.030 回答