【问题标题】:Run an async loop indefinitely from button click from Xamarin从 Xamarin 中单击按钮无限期地运行异步循环
【发布时间】:2018-02-18 18:49:01
【问题描述】:

与应用程序无限并行运行循环的最佳方式是什么?

这是我迄今为止尝试过的:

激活循环的按钮:

private void ActiveDeactiveTest(object sender, EventArgs e)
{
    active = !active;            
}

循环:

bool runTest = false;
bool active = false;
public async void Test()
{
    while (runTest)
    {
       if (active)
       {
           LblOutput.Text = "before";
           await Task.Delay(1000);
           LblOutput.Text = "after";
        }
        else
        {
           LblOutput.Text = "Idle";
        }
    }
}

以及表单实例化:

public MainPage()
{
    InitializeComponent();
    runTest = true;
    Test();
}

对此相当陌生,因此我们将不胜感激 提前致谢

【问题讨论】:

  • 你应该在一个单独的线程上运行它,而不是 UI 线程
  • @Jason 当然,但我无法访问 'Thread thread = new Thread(function);'在 Xamarin 中

标签: c# android visual-studio asynchronous xamarin


【解决方案1】:

我认为没有最佳的无限循环方式,但我会提供一些选项。想法是从您的主应用程序线程启动另一个线程并利用循环(通常是 while)来管理无限循环。

如果您正在开发 UI 应用程序,请务必小心,因为它们在后台工作方面非常敏感。例如,WPF 仅允许创建 UI 元素的线程(称为 Dispatcher 的线程)访问 UI 元素。这意味着每个需要更新 UI 元素的后台线程都需要将工作委托给调度线程。 android也是这样,区别在于Dispatcher线程称为UI线程(WPF Dispatcher Thread,Android UI Thread

WPF

在 WPF 中,DispatcherObject 只能由与其关联的 Dispatcher 访问。例如,后台线程无法更新与 UI 线程上的 Dispatcher 关联的 Button 的内容。为了让后台线程访问 Button 的 Content 属性,后台线程必须将工作委托给与 UI 线程关联的 Dispatcher。这是通过使用 Invoke 或 BeginInvoke 来完成的。 Invoke 是同步的,而 BeginInvoke 是异步的。操作被添加到指定 DispatcherPriority 的 Dispatcher 队列中。

安卓

Android UI 工具包不是线程安全的。因此,您不能从工作线程操作您的 UI — 您必须从 UI 线程对您的用户界面进行所有操作。因此,Android 的单线程模型只有两条规则:

  1. 不要阻塞 UI 线程
  2. 不要从 UI 线程外部访问 Android UI 工具包

我将提供几个示例作为展示案例:

//Option A, common one, loop doesn't need to have iteration at all
Task.Factory.StartNew(() =>
{               
    while (shouldLooping)
    {
        //do your job
    }
});

//Option B, kind of wierd, loop will have at least one iteration
Task.Factory.StartNew(() =>
{               
    do
    {
        //do your job
    } while (shouldLooping);
});

//Option C, if you are driven by producer/consumer pattern, BlockingCollection should be shared between producer and consumer
Task.Factory.StartNew(() =>
{
    foreach (var item in blockingCollection.GetConsumingEnumerable())
    {
        Console.WriteLine(item);
    }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 2017-10-19
    • 1970-01-01
    • 1970-01-01
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    相关资源
    最近更新 更多