这些是我提出的不要使用Control.Invoke的解决方案。
IMainView、MainView 和 Program 的代码在两种解决方案中是相同的:
IMainView
namespace Tester1
{
interface IMainView
{
string ControlProperty { get; set; }
}
}
主视图
using System.Windows.Forms;
namespace Tester1
{
public partial class MainView : Form, IMainView
{
public MainView()
{
InitializeComponent();
}
public string ControlProperty
{
get => MyControl.Text;
set => MyControl.Text = value;
}
}
}
程序
using System;
using System.Windows.Forms;
namespace Tester1
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// models
EventRaisingObject eventRaisingObject = new EventRaisingObject();
// views
MainView mainView = new MainView();
// presenters
MainPresenter mainPresenter = new MainPresenter(mainView, eventRaisingObject);
Application.Run(mainView);
}
}
}
解决方案 1:使用SynchronizationContext
主演讲者
using System.Threading;
namespace Tester1
{
class MainPresenter
{
private readonly IMainView mainView;
private readonly EventRaisingObject eventRaisingObject;
private readonly SynchronizationContext viewContext;
public MainPresenter(IMainView mainView, EventRaisingObject eventRaisingObject)
{
this.mainView = mainView;
viewContext = SynchronizationContext.Current;
this.eventRaisingObject = eventRaisingObject;
this.eventRaisingObject.MyEvent +=
(sender, s) => viewContext.Post(d => OnMyEvent(s), null);
}
private void OnMyEvent(string e)
{
// do some work
mainView.ControlProperty = e;
// do some work
}
}
}
此解决方案使用SynchronizationContext 对象,在构造函数中使用 UI 的上下文进行初始化。
解决方案 2:使用TaskFactory
using System.Threading.Tasks;
namespace Tester1
{
class MainPresenter
{
private readonly IMainView mainView;
private readonly EventRaisingObject eventRaisingObject;
private readonly TaskFactory viewTaskFactory;
public MainPresenter(IMainView mainView, EventRaisingObject eventRaisingObject)
{
this.mainView = mainView;
viewTaskFactory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
this.eventRaisingObject = eventRaisingObject;
this.eventRaisingObject.MyEvent +=
(sender, s) => viewTaskFactory.StartNew(() => OnMyEvent(s));
}
private void OnMyEvent(string e)
{
// do some work
mainView.ControlProperty = e;
// do some work
}
}
}
此解决方案使用 TaskFactory 对象,在构造函数中使用 UI 的 TaskScheduler 进行初始化。引发事件时,使用 TaskFactory 对象启动新任务。