15

I want to execute the following

MainPage = new ContentPage
{
    Content = new StackLayout
    {
        Children =
        {
            new Button
            {
                Text = "Thread.Sleep",
                Command = new Command(() =>
                {
                    Thread.Sleep(1000);
                    MainPage.Animate("", x => MainPage.BackgroundColor = Color.FromRgb(x, x, x));
                }),
            },
            new Button
            {
                Text = "Task.Run + Thread.Sleep",
                Command = new Command(async () =>
                {
                    await Task.Run(() => Thread.Sleep(1000));
                    MainPage.Animate("", x => MainPage.BackgroundColor = Color.FromRgb(x, x, x));
                })
            },
            new Button
            {
                Text = "Device.StartTimer",
                Command = new Command(() => Device.StartTimer(
                    TimeSpan.FromSeconds(1),
                    () =>
                    {
                        MainPage.Animate("", x => MainPage.BackgroundColor = Color.FromRgb(x, x, x));
                        return false;
                    })),
            },
        }
    }
};

I included System.Threading and System.Threading.Tasks, but I still get

The name 'Thread' does not exist in the current context.

This site suggests that Thread.Sleep can be used in Xamarin.Forms. I have this in a shared project, not a PCL.

testing
  • 19,681
  • 50
  • 236
  • 417
  • 1
    `Thread.Sleep` should be avoided while using almost all UI frameworks (WinForms/WPF/Xamarin.Forms/Silverlight/...) as it freezes the UI thread and hangs the UI. – Lex Li Mar 03 '16 at 12:52
  • It is only for demonstration purposes, but thanks for your addition. – testing Mar 03 '16 at 14:30

2 Answers2

40

If you want to wait

asynchronously: await Task.Delay(10000);

synchronously: Task.Delay(10000).Wait();

But please try to avoid blocking the UI thread to ensure a good user experience and keep your app responsive.

Using Thread.Sleep in Xamarin.Forms

There are two Xamarin.Forms templates:

  • Xamarin.Forms Portable Class Library

    Because of the PCL subset mechanism, you have no chance to get Thread.Sleep.

    Update 2017: PCLs are deprecated, now. If you use .netstandard 2.0, you can use Thread.Sleep as you are used to it.

  • Xamarin.Forms Shared Project

    This Template contains different platforms that do not support Thread.Sleep. Windows UWP, Xamarin.Android and Xamarin.iOS support it, Windows Phone 8.1, and Windows 8.1 not. If you unload/delete the 2 projects, the solution builds. (don't forget using System.Threading; in your App.cs)

Sven-Michael Stübe
  • 14,560
  • 4
  • 52
  • 103
  • You are right that the UI thread should not get blocked. Here it is only for demonstration purposes. – testing Mar 03 '16 at 09:24
  • Do you have an idea why `Thread` isn't recognized? On the linked page it seems that it somehow works. – testing Mar 03 '16 at 09:27
  • 1
    I think you don't have `Thread.Sleep` because of a different PCL profile of your Core library. The more supported platforms you select in the PCL, the less supported classes / functions you can use. – Sven-Michael Stübe Mar 03 '16 at 09:35
  • Any ideas where this can be changed? – testing Mar 03 '16 at 09:37
  • If you use a `Shared Library` instead of a `Portable Class Library`, it should work. But be aware, that some platforms simply don't support `Thread.Sleep` (e.g. WinPhone 8.1) – Sven-Michael Stübe Mar 03 '16 at 09:39
  • I tried it in a new `Blank App (Xamarin.Forms Shared)` and I get the same behavior. Strange ... – testing Mar 03 '16 at 09:58
  • 1
    This is because the Template contains different platforms that do not support `Thread.Sleep`. Windows UWP, Xamarin.Android and Xamarin.iOS support it, Windows Phone 8.1, and Windows 8.1 not. if you unload/delete the 2 projects, the solution builds. (don't forget `using System.Threading;` in your App.cs. – Sven-Michael Stübe Mar 03 '16 at 10:12
  • That is the solution. Please edit you answer and I'll give you the tick. – testing Mar 03 '16 at 10:22
  • I summarized it in the answer. – Sven-Michael Stübe Mar 03 '16 at 10:32
4

You can try to use

await Task.Delay(milliseconds);

if you want to put a delay in your thread.

For blocking you can do

Task.Delay(TimeSpan.FromSeconds(5)).Wait();
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • You could do that, but that is different from the example I want to try. The thread should get blocked with the first button not delayed. Do you have an idea what I'm missing? A reference in the sub projects? – testing Mar 03 '16 at 09:20
  • @testing:- Updated my answer to block it. Please check – Rahul Tripathi Mar 03 '16 at 09:23