-1

I have an application, when a button is clicked, it starts a task which connects to a specific bluetooth device and then have a continuous stream of data coming in and going out. When the user clicks on the button again, I'd like it to check, if the task I created the first time is running, and if it is, terminate the task. I was thinking of cancelling the task with CancellationToken, but I can't get passed of checking if the task is running or not. Right now, when I click the button the first time, it creates the task and does everything nicely. When I click the button the second time, it still goes past the if statement, thinking the task isn't running and tries to create the task again and connect the bluetooth device again the then gets stuck.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using InTheHand;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Ports;
using InTheHand.Net.Sockets;
using System.IO;
using System.Threading;

namespace app
{
class Bluetooth
{
    Guid mUUID = new Guid("00001101-0000-1000-8000-00805F9B34FB");
    public BluetoothClient client;
    BluetoothDeviceInfo[] devices;
    private Task connectionTask;              



    private void Connect() //This is called from button click
    {
        if (connectionTask == null ||
            connectionTask.IsCompleted == false &&
            connectionTask.Status != TaskStatus.Running && 
            connectionTask.Status != TaskStatus.WaitingToRun && 
            connectionTask.Status != TaskStatus.WaitingForActivation)
           {
            connectionTask = Task.Factory.StartNew(ConnectionTask);
           }

        else
        {
            var form1 = new Form1();
            form1.message("Client already connected", 3);                  
        }            
    }

    private void ConnectionTask()
    {
        //Do Bluetooth connection stuff here which, once connected, will stay in an infinite while loop. 

    }
 }
}

Ive changed the code to the following, but still only get Client connected messagebox. As I understand, because I have Thread.Sleep(100000) the Task should still count as running?

class Bluetooth
{


    private Task connectionTask;


    public void bluetooth()
    {
        Connect();
    }

    private void Connect()
    {


        if (connectionTask == null ||
        connectionTask.IsCompleted == false &&
        connectionTask.Status != TaskStatus.Running &&
        connectionTask.Status != TaskStatus.WaitingToRun &&
        connectionTask.Status != TaskStatus.WaitingForActivation)
        {
            connectionTask = Task.Factory.StartNew(ConnectionTask);
        }

        else
        {
            var form1 = new Form1();
            form1.message("Client already connected", 3);                  
        }            
    }

    private void ConnectionTask()
    {

        var form1 = new Form1();
        form1.message("Client connected", 1);
        Thread.Sleep(100000);

    }
}
}
Rikas
  • 23
  • 1
  • 6
  • please don't correct your answer but [accept](https://meta.stackexchange.com/a/5235) an answer – NtFreX Jun 05 '17 at 14:22

2 Answers2

1

The problem is, that you create a new Task (and overwrite the instance variable) before checking if the task finished. Just remove the line connectionTask = new Task(ConnectionTask); and additionally check for connectionTask == null should solve it.

JanDotNet
  • 3,746
  • 21
  • 30
  • I've changed the code to this: ' if (connectionTask == null && connectionTask.IsCompleted == false && connectionTask.Status != TaskStatus.Running && connectionTask.Status != TaskStatus.WaitingToRun && connectionTask.Status != TaskStatus.WaitingForActivation) ' But now it gives System.NullReferenceException: 'Object reference not set to an instance of an object.' connectionTask was null. – Rikas Jun 05 '17 at 13:25
1

As @JanDotNet stated if you initialise the connectionTask variable before the if statement it will not work.

You will have to rewrite your if statement to the following.

if (connectionTask == null ||
    connectionTask.IsCompleted == false &&
    connectionTask.Status != TaskStatus.Running && 
    connectionTask.Status != TaskStatus.WaitingToRun && 
    connectionTask.Status != TaskStatus.WaitingForActivation)
{
    connectionTask = Task.Factory.StartNew(ConnectionTask);
}
NtFreX
  • 10,379
  • 2
  • 43
  • 63
  • I've tried this as well, but it goes in the if loop on the second time also and the whole thing gets stuck. It says the task isn't null (even though I removed the = new Task() and only private Task connectionTask is left) and all the rest of comparisons are true aswell. – Rikas Jun 05 '17 at 13:44
  • @siimrikas Take a look at the implementation [here](http://rextester.com/KPA53847). Its working there. Maybe the task doesn't run forever but stops? – NtFreX Jun 05 '17 at 13:47
  • In the private void ConnectionTask() it goes through with scanning for clients, connecting to a client and prompts me with a messagebox confirming connection. After that, I have while(true) loop set to simulate the infinite stream I'd like to get out of it, and if I have a breakpoint at the while loop, it gets stuck there like it should. Then after pressing the button again, by all means, the task should be running, but the if statement doesn't recognise that. – Rikas Jun 05 '17 at 14:14
  • Is ConnectionTask running on the same thread as connectionTask. Don't know where to look or what to do anymore. I'm not an experienced programmer and just learning my way as I go so most likely I'm missing something, probably very obvious and simple. – Rikas Jun 05 '17 at 14:14
  • @siimrikas I would reduce your code and test the parts each after another. If you will test the code you posted here and the corrections you will see that it works. And without knowledge about the other code its hard to say what isn't working. I would put your focus on the other part not on the task and the if statement which works now. – NtFreX Jun 05 '17 at 14:22
  • 1
    Works! I changed my code over to the one you added. Dont know what I did wrong but will go over my code and try to figure out. Thank you very much for you help! – Rikas Jun 05 '17 at 14:52