1

I am trying to create a custom thread class, but when I call its functions it blocks my UI thread. What I mean is that when I press the button, it stays pressed until the task completes.

This is the Main Activity:

using Android.App;
using Android.Widget;
using Android.OS;
using Java.Lang;

namespace ThreadTest08 {
    [Activity(Label = "ThreadTest08", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity {

        protected override void OnCreate(Bundle bundle) {
            base.OnCreate(bundle);

            SetContentView(Resource.Layout.Main);
            Button button = FindViewById<Button>(Resource.Id.MyButton);

            button.Click += delegate {
                MyThreadClass mtc = new MyThreadClass();
                mtc.Start();
                mtc.DoSomething();    
            };    
        }
    }
}

And this is the class:

using Java.Lang;

namespace ThreadTest08 {
    class MyThreadClass : Thread {    
        public void DoSomething() {
            Thread.Sleep(3000);
        }
    }
}

Why is this happening? Thanks for reading.

NikosD
  • 125
  • 10
  • Hi, I would like to add this [link](http://stackoverflow.com/questions/8123461/unable-to-inherit-from-a-thread-class-in-c-sharp) to this section because I think it is relevant. The reason I used "using Java.Lang;" in code is because it allowed me to create a class that inherits from the Thread class. If I try this using "using System.Threading" then the code does not compile saying that Thread is a sealed class. Since Java.lang allows inheritance on the Thread class, is there any way to prevent the inherited thread to run on the UI and lock it? – NikosD Nov 24 '16 at 13:26
  • If your question is answered please accept that answer. – 476rick Dec 23 '16 at 07:40
  • I'm sorry but all the answers are off topic and I cannot accept. – NikosD Jan 03 '17 at 08:46
  • Since "MyThreadClass" inherits from "Thread" why does it not behave like a thread? – NikosD Jan 03 '17 at 08:51

2 Answers2

2

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.

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. 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)

source

EDIT: The UI thread freezes because your custom thread makes your UI thread wait. The actions you do in your custom thread run on the UI thread.

You could use async methods to execute the code you showed in your comment. I think that would accomplish what you need.

Community
  • 1
  • 1
476rick
  • 2,764
  • 4
  • 29
  • 49
  • Hi thanks for the reply. Actually this is a cut down version of what I am coding. The "Thread.Sleep(x)" is just there to indicate some task execution, which in my current project contains BlueTooth comms. Even if I type something like: public void DoSomething() { for(int i=0; i<10000000; i++) { int j = (int)System.Math.Sqrt(i); } } The same thing happens. – NikosD Nov 22 '16 at 14:17
  • You ask why the UI freezes, that is because you use Thread.Sleep(x) – 476rick Nov 22 '16 at 14:21
  • The thread you are executing, does its work on the UI thread I guess. – 476rick Nov 22 '16 at 14:28
0

You can do as the following code

button.Click += MyButtonClick;

private async void MyButtonClick(object sender, EventArgs e)
{
    button.Text="Working";
    await Task.Run(async () =>
    {
        await Task.Delay(3000); //or whatever you need
         Device.BeginInvokeOnMainThread(() => {
           button.Text="Done";
         });

    });
}
Nick Kovalsky
  • 5,378
  • 2
  • 23
  • 50
Yuri S
  • 5,355
  • 1
  • 15
  • 23