Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVP&x2B;互动者_C#_Android_Xamarin_Xamarin.android - Fatal编程技术网

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
    (按系统):用户界面
  • OnRefresh
    (1):用户界面
  • ReadDb
    (2):工人
  • SetData
    (3):用户界面
我可以通过使
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(()
样板代码无处不在。我也会在帖子中向其他人说明这一点。