-2

I used raspberry pi 3 and Windows IoT build an RFID reader. When I copy this lib RFID RC522 Raspberry PI 2 Windows IOT and make new class for this lib. I have some problem.

In original namespace, I add a new class 'startmfrc522'.

public class startmfrc522 {

Mfrc522 mfrc = new Mfrc522();
    public async Task<bool> start() {
        System.Diagnostics.Debug.WriteLine("start RFID");
        await mfrc.InitIO();
        System.Diagnostics.Debug.WriteLine("finish Init");
        return true;
    }

    public async Task<string> readtag() {
        for (int i = 0; i < 5; i++) {
            System.Diagnostics.Debug.WriteLine("start read tag");
            if (mfrc.IsTagPresent()) {
                System.Diagnostics.Debug.WriteLine("success");
                string uid = mfrc.ReadUid().ToString();
                mfrc.HaltTag();
                return uid;
            }
            else {
                mfrc.HaltTag();
                return "fail";
            }
            await Task.Delay(1000);
            System.Diagnostics.Debug.WriteLine("Delay for 1 s");
        }
        return "fail";
    }
}

In the mainpage, I use this code to start the rfid reader and read tag

        startmfrc522 rfid = new startmfrc522();

        while (!rfid.start().Result){
            System.Diagnostics.Debug.Write(".");
        }
        System.Diagnostics.Debug.WriteLine(rfid.readtag());

First problem is VS 2015 told me use 'bool x = await start()', I change it to 'bool result = await start()', still not working.

Second problem is I test read the tag, looks like mfrc.InitIO not finish and immediately read the tag. But I add the 'async' and 'await', shouldn't it will wait the InitIO finish the work and read the tag?

Third problem is 'Task.Sleep' not working, I think it should be wait for five times and total wait for 5s.

I think I'm not really understand the 'await' and 'async'. Hope someone could tell me what is it and how to change my code to work!

Community
  • 1
  • 1
LittleTin
  • 23
  • 7
  • Can you define 'not working'? – Patrick Hofman Dec 30 '16 at 14:21
  • 2
    ` Task.Delay(1000);` should be `await Task.Delay(1000);` otherwise there is no delay. Also *where* did you call `await start();`? Console applications can't use `async/await` in their main function - there is no point. There is foreground thread that needs releasing. You'd have to use `var x=start().Result;` – Panagiotis Kanavos Dec 30 '16 at 14:22
  • it tell me use the 'async' and return 'Task' – LittleTin Dec 30 '16 at 14:26
  • Do so then, in the method that calls `start()`. You have to put `async` in the function header in order to use `await` in the body. You already did this in the other functions – Panagiotis Kanavos Dec 30 '16 at 14:32
  • Post the method that calls `rfid.start()`. That's where the problem is – Panagiotis Kanavos Dec 30 '16 at 14:34
  • Hey, I had update my code at the question, the new problem is console will show "start RFID" but won't show "finish Init", it looks like freezing. And I have success use this lib and read tag in mainpage but I want make it in a class. – LittleTin Dec 30 '16 at 14:40
  • Don't do `System.Diagnostics.Debug.WriteLine(myFunc())`, as `myFunc` won't be called when you change your project to release mode. – chue x Dec 30 '16 at 14:42
  • looks like '_spi = await SpiDevice.FromIdAsync(devices[0].Id, settings);' this line stuck the system. – LittleTin Dec 30 '16 at 15:15

1 Answers1

1
  1. readtag should be public async Task<string> readtag()
  2. readtag should use await Task.Delay(1000);
  3. start should call System.Diagnostics.Debug.WriteLine(await readtag());
  4. method that you called "mainpage" should call await rfid.start() and await rfid.readtag() and should be Task based as well ( async Task mainpage())
Simon Luckenuik
  • 345
  • 4
  • 12
  • `readtag()` isn't asynchronous, it returns a simple string. Only `await Task.Delay()` is wrong, and that's not the OP's problem anyway. It seems there is *another* method which calls `start()` that doesn't have the `async/await` – Panagiotis Kanavos Dec 30 '16 at 14:34
  • OP is asking about how to use async and await, so I explain that and how to convert his code to be Task based since his sample code uses Tasks. Method is not only returning a simple string, it's doing a delay as well, using Task.Delay will be more efficient than Thread.Sleep [link](http://stackoverflow.com/a/20084603/6775223) – Simon Luckenuik Dec 30 '16 at 14:40
  • Hey, I had update my code at the question, the new problem is console will show "start RFID" but won't show "finish Init", it looks like freezing. And I have success use this lib and read tag in mainpage but I want make it in a class. – LittleTin Dec 30 '16 at 14:41
  • @LittleTin, it means that "await mfrc.InitIO();" is blocking for some reason. Keep in mind that using Task in method signature isn't spawning threads for you, so if InitIO takes 5 minutes and no thread is started, than await will block on InitIO for 5 minutes. If you need to start threads, have a look at TaskFactory: https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskfactory(v=vs.110).aspx – Simon Luckenuik Dec 30 '16 at 14:44
  • Got It, before I trying this new way, I remove the await and use Task.Delay(10000); in main page. It's work to read tag, but I hope to use safety way to init rfid IO, – LittleTin Dec 30 '16 at 14:53
  • looks like '_spi = await SpiDevice.FromIdAsync(devices[0].Id, settings);' this line stuck the system. – LittleTin Dec 30 '16 at 15:15
  • Your await usage is OK, looks like a SDK/hardware issue now. :) – Simon Luckenuik Dec 30 '16 at 15:19
  • Thanks, but I have a new problem, When I get the Task, it looks like return "Task.Delay()", I won't get anything from the 'real return' – LittleTin Dec 30 '16 at 17:45
  • Please update your original question with more information, I don't understand what you mean. When you have a method that returns Task and use the async keyword, you need to return a value like usually "return something;". Task.Delay doesn't return any value (Task, not Task), so you cannot return Task.Delay where Task is required. – Simon Luckenuik Dec 30 '16 at 18:05