我有一个使用MVP模式的winforms应用程序,如本文所述 http://www.codeproject.com/Articles/563809/UIplusDesignplusUsingplusModel-View-Presenter我正在将我的应用转换为异步/等待但遇到问题。
这是一个说明我的问题的例子
Bodies.circle(x, y, 46, {
render: {
sprite: {
texture: 'images/stone.png'
//Is there a 'width:' or 'height' property?
}
}
});
此代码无法正常等待,并且当抛出异常时,它不会被捕获。这是因为异步无效。当这段代码不是异步/等待时,异常被抓住了。
我知道异步无效是一个不可以除了顶级事件,但我的应用程序的设计方式我真的无法解决这个问题。当我只有一个用户时,我将IView接口更改为
public interface IView
{
event Action DoSomething;
}
public partial class MyForm : Form, IView
{
public event Action DoSomething;
public MyForm()
{
InitializeComponent();
}
private async void OnSomeButtonClick(object sender, EventArgs e)
{
if (DoSomething!= null)
{
try
{
await DoSomething();
SomeOtherMethod();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
public class MyPresenter
{
private readonly IView _view;
private ClassWithAwaitbleMethods _foo;
public MyPresenter(IView view)
{
_view = view;
_view.DoSomething += OnDoSomething;
_foo = new ClassWithAwaitableMethods();
}
public async void OnDoSomething()
{
//this may throw an exception
await _foo.SomeAwaitableWork1();
}
}
public class MySecondPresenter
{
private readonly IView _view;
private ClassWithAwaitbleMethods _foo;
public MySecondPresenter(IView view)
{
_view = view;
_view.DoSomething += OnDoSomething;
_foo = new AnotherClassWithAwaitableMethods();
}
public async void OnDoSomething()
{
//this may throw an exception
await _foo.SomeAwaitableWork2();
}
}
并像这样连接起来
public interface IView
{
Func<Task> DoSomething {get; set;};
}
哪个是hacky但正等待事情并抓住异常。 任何帮助或见解将不胜感激。
答案 0 :(得分:2)
核心问题是代码使用事件作为策略模式而不是观察者模式。你现在所处的代码并没有太大的作用;适当的重构需要回调接口而不是事件。 E.g:
// An instance of this is passed into the concrete view.
public interface IViewImplementation
{
void DoSomething();
// Or the async equivalent:
// Task DoSomethingAsync();
}
但是,如果重构级别令人讨厌,则可以应用一些变通方法。我在我的博客上报道了这样的"async events"。有几种方法;定义Task
- 返回事件是可能的(尽管很尴尬)。不过,我最喜欢的方法是Deferrals,主要是因为延迟是WinRT开发人员已经熟悉的概念。