C# MVP&x2B;互动者
考虑到以下流程: 我希望这些线程执行这些方法:C# MVP&x2B;互动者,c#,android,xamarin,xamarin.android,C#,Android,Xamarin,Xamarin.android,考虑到以下流程: 我希望这些线程执行这些方法: OnClick(按系统):用户界面 OnRefresh(1):用户界面 ReadDb(2):工人 SetData(3):用户界面 我可以通过使ReadDb异步并等待它来实现这一点,但它会冻结UI线程 您能想出一种不涉及实现交互器、异步任务等的方法吗 谢谢 编辑 我正在寻找一个优雅的解决方案,请避免在视图的每个方法中都有像新处理程序(Looper.getMainLooper()).post(…),RunOnUiThread这样的包装 最简单的
(按系统):用户界面OnClick
(1):用户界面OnRefresh
(2):工人ReadDb
(3):用户界面SetData
ReadDb
异步并等待它来实现这一点,但它会冻结UI线程
您能想出一种不涉及实现交互器
、异步任务
等的方法吗
谢谢
编辑 我正在寻找一个优雅的解决方案,请避免在
视图的每个方法中都有像新处理程序(Looper.getMainLooper()).post(…)
,RunOnUiThread
这样的包装
最简单的方法是使用taskt
和wait
:
async OnRefresh() {
data = await m.ReadDb()
v.SetData(data)
}
但是,UI在上冻结,等待m.ReadDb()
。我认为因为OnRefresh
返回void
,它将返回并完成父方法的执行(OnClick
)。然后,一旦wait
完成,它将执行v.SetData(d)
。出于某种原因,我得到的不是输出。类似这样的东西:
class View {
IPresenter p;
void onClick() {
p.OnRefresh()
}
void setData() {
}
}
class Presenter implements Listener {
void OnRefresh() {
// You can do it with newThread or anything that does async
async (
m.readDB()
)
}
void onComplete(Data data) {
// or you can put it on Model class.
new Handler(Looper.getMainLooper()).post(() -> {
// this will be run on ui (or main) thread.
v.setData(data);
})
}
}
class Model {
Listener lstr;
void readDB() {
// read data..
// completed
lstr.onComplete(data)
}
}
interface Listener {
void onComplete(Data data)
}
您还可以添加onFailure()和其他方法,而且RxJava使这一点变得非常简单
注意:这里您需要担心的另一件事是循环引用,这是由于视图对presenter有引用,而presenter对视图有引用造成的。一旦不再需要ref,就需要手动销毁它(可能是onDestroy),否则会发生内存泄漏。实际上,我的方法是正确的,但实现是不正确的。我希望等待m.ReadDb()
在工作线程中运行,但事实并非如此。这样做的原因是,我必须通过Task.Run
和wait
明确地请求它:
OnRefresh()
{
var d = await Task.Run (() => m.ReadDb());
v.SetData(d)
}
仅仅编写wait
并不会创建新线程,这就是UI被阻止的原因
检查,它被指给我的地方。为什么需要等待它?您可以执行ReadDb
async,加载数据后将其发送到主线程并执行v.setData…@SabaJafarzadeh您所说的将其发送到主线程
是什么意思?意味着在ui线程上运行它。(由Handler(Looper.gerMainLooper()
)感谢Saba,不幸的是,我不喜欢这种方法。我不希望每次调用模型,都有侦听器,也不希望新的处理程序(Looper.getMainLooper()).post(()
样板代码无处不在。我也会在帖子中向其他人说明这一点。