-1

I'm currently learning Android programming and I'm doing my first application using VS 2017 in C# (Xamarin). Right now I'm trying to understand how to split a complex computation into several threads - more accurately, the features I should look into.

Now, what I want to do is to iterate over all possible values of an unsigned int and perform some computation on it. It's a search, so some of those numbers will be of interest and I need the threads to update a progress bar and some view containing any results found so far. The complexity here is the huge number of operations that will be performed.

I've looked into Async Tasks, Thread Pool Executor, Thread Factory, Blocking Queues and Runnables. So I'm thinking a Thread Pool sounds like the way to go, especially by specifying how many processors are available and how many threads can be used.

Going by this SO question/answer, I would use an Async Task for a short operation and Java threads for more complex operations. So, despite using C# Xamarin, I guess I'm looking into Javal.Util.Concurrent.Thread's..

My goal with all this, is to allow the user to start this complex task and pause it at any point, or abort, as well as save the search state at any point to resume later. To do this, I want to subdivide this search on all possible uint values into multiple tasks - perhaps thousands of small tasks that could be executed by worker threads. For the pause feature, I was thinking the example in Android's documentation, that I previously linked, which implements Pause/Resume methods in a custom Thread Pool Executor. The save/store should be easy.. if my tasks are ordered all I need is to keep track of the last value tested and fruitful values.

I've setup a custom Thread Pool Executor, Factory and Runnables. However, I am quite confused as to how to do two things:

  • How exactly should I add runnables to the queue? And from which thread?

  • How, and where, do I know when the search was completed? What happens to the minimum number of threads in the Thread Pool Executor when the job is completed? I want to destroy all the threads when it's over.

In my operations I could have thousands of tasks. In fact, I can decide between 4096 large tasks, or 65536 smaller tasks. They can be identified by a range of uints to be checked, or a single uint index. But either way I know ahead of time how many they are and I think it would be more efficient if I didn't have to create that many runnables... Is there a way I can customize how the threads will pick up their next work from the Queue?

Or perhaps the Thread Pool Executor is just not the right tool for what I'm trying to achieve here?

I'm mostly looking for some insight on the multithreading tools available in Android and how can I go about implementing a proper solution for my problem.

aslg
  • 1,966
  • 2
  • 15
  • 20
  • Is the code that you are running within those "tasks" purely C#/CIL-based, purely Java (*assuming* not since you are using Xamarin, but it could be contained in a Jar/Aar) and it is crossing the C#/Java JNI bridge on each iteration? i.e. What is the frequency of displaying data from the task in an Android Java-based widget? – SushiHangover Mar 31 '18 at 21:42
  • @SushiHangover Well the code itself is purely C#. It's just a loop and some checks. I've tried to just run an Async Task and it worked fine (and slow with just 1 thread), but I'm trying to make it work with a ThreadPoolExecutor as well and see how it goes. And that part is a Java binding. So, C# code running on Java threading? And about the displays.. I want to update a progress bar when a task ends, and the results as soon as possible, which is like 1 result per search. *Maybe* 2. So most tasks will find nothing. But, is there some sort of performance hit using C# and Java like that? – aslg Apr 01 '18 at 00:51
  • If it is all C# code, stay on the CIL Managed side of things and avoid the Java as there is not need for it (and yes there is a perf. penalty depending upon how many times you have to cross the Mono/JNI/Java bridge). C# (Mono) has all the concurrent/parallel threading frameworks that you need. – SushiHangover Apr 01 '18 at 02:51
  • @SushiHangover Surely enough I was able to use C# threads to accomplish the job. The entire thing works properly but I'm still managing these threads locally. Thanks. I'll have to try C#'s own Thread Pool later. – aslg Apr 03 '18 at 16:57

1 Answers1

0

You should definitely have a look to reactive programming http://reactivex.io/ and https://github.com/ReactiveX/RxJava

This is the best and cleanest way to execute tasks in background, for example you could do :

 myObservable
    .subscribeOn( Schedulers.io() ) // Thread where you execute your code
    .observeOn( AndroidSchedulers.mainThread()) / Thread where you get result
    .subscribe(...)
Samuel Eminet
  • 4,647
  • 2
  • 18
  • 32