【问题标题】:How can I use threading in MonoDroid such that it will be cross platform compatible with MonoTocuh如何在 MonoDroid 中使用线程,使其与 MonoTocuh 跨平台兼容
【发布时间】:2013-04-10 19:52:53
【问题描述】:

特别是当 MonoDroid 使用线程时,我能找到的所有文档都建议调用 RunOnUiThread() 来调用回调。有一个类似的功能可以在 MonoTouch 上使用,但是它们都需要一个 GUI(活动或任何它在 IOS 上的对应部分)。我想要的是能够启动一个线程,传入一个回调并在启动线程的线程上调用该回调。例如

ThreadPool.QueueUserWorkItem(state =>
{
    //Do Stuff


    execute_callback_magically_on_main_thread(() => callback(response));
});

有什么想法吗?为了清楚起见,我希望这不需要 Activity 等的句柄。

【问题讨论】:

  • 为什么不直接引发一个事件,让视图自己决定如何以自己的平台特定机制将其编组到 UI 线程?

标签: multithreading mono xamarin.ios xamarin.android


【解决方案1】:

如果你做这样的事情怎么办? (假设他们有相同的签名)我没有弄乱RunOnUiThread,所以我不知道它的签名。

    public delegate void InvokeOnUIMethod(Action action);

    public void CallingMethod()
    {
        //iOS
        MyMethod(InvokeOnMainThread, () => { /* Your callback functionality  */ });

        //Android
        MyMethod(RunOnUiThread, () => { /* Your callback functionality  */ });
    }

    public void MyMethod(InvokeOnUIMethod execute_callback_magically_on_main_thread, Action callback)
    {
        System.Threading.ThreadPool.QueueUserWorkItem(state =>
        {
            //Do Stuff

            execute_callback_magically_on_main_thread(() => callback(response));
        });
    }

我希望这会有所帮助。

【讨论】:

  • 这也是我的第一个想法。但是为了让它在android上工作,你必须引用Activity,而在IOS中你必须引用NSObject。我正在从库中进行这些调用,因为我试图从我的 ui 中分割我的逻辑,所以拥有这些引用并不容易。我可以超越它们,但它们并没有真正的共同祖先。
【解决方案2】:

使用 Alpha 版本(希望很快可以稳定使用),您可以使用新的 Async await 习惯用法。

这是 MSDN 上的概述:

http://msdn.microsoft.com/en-gb/library/vstudio/hh191443.aspx

这是 Channel9 上的精彩视频系列:

http://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Tip-1-Async-void-is-for-top-level-event-handlers-only

【讨论】:

    【解决方案3】:

    我找到了一个可行的解决方案,并且似乎不依赖于任何一个平台。

    Task<string> t = new Task<string>(() =>
    {
        //Do Stuff
        return "my results";
    });
    t.ContinueWith(task =>{
        if(callback != null)
             callback(task.Result);
        }, TaskScheduler.FromCurrentSynchronizationContext());
    t.Start();
    

    重要的部分是 TaskScheduler.FromCurrentSynchronizationContext(),它告诉“ContinueWith”在原始线程上执行。

    【讨论】:

    • 我认为重点是您需要在 UI 线程上执行某些操作,而不是仅仅能够执行后台任务?
    • 我需要的是能够在 UI 线程上执行的东西,只要 UI 线程启动它就可以了。由于“FromCurrentSyncronizationContext()”调用,ContinueWith 部分在父线程上执行。
    猜你喜欢
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多