4

我是 C# 新手,目前正在开发支持 PIN 键盘的后端代码。基本上,我的代码

OpenDevice() -> RequestPIN() 
-> key in PIN on PIN PAD -> GetResultPIN() 
-> ConsolePrintOutPIN() -> Print keyed PIN on the Console 

我不知道如何为此编写线程,这样一旦在 PIN 后在设备上按下“Enter 键”,系统就会自动滚动运行GetResultPIN()。因此,根据我的基本知识,我编写了以下代码Console.ReadLine()来分隔每个过程:

    static void Main(string[] args)
    {
        // 1. Open PIN Pad device
        OpenDevice();

        Console.ReadLine();// to hold up from the previous procedure, it is *not* for input data purpose

        // 2. Request PIN from PIN Pad device.
        //    On the PIN Pad device, it reads:
        //    "Key in the PIN:     "
        RequestPIN();

        Console.ReadLine();// to hold up from the previous procedure, it is *not* for input data purpose

        // 3. get PIN from the device
        GetResultPIN();

        // 4. Print out on the Console 
        ConsolePrintOutPIN();

        Console.ReadLine();// to hold up from the previous procedure, it is *not* for input data purpose
    }

问题:谁能给我任何关于如何使用可以避免使用的线程/事件/委托的建议Console.ReadLine()

如上所述,Console.ReadLine()仅用于停止程序(抱歉我以这种方式使用它的天真......)一旦我使用Console.ReadLine(), between RequestPIN()and GetResult(),系统至少会等待我从 PIN PAD 输入 PIN (通过 USB 连接到计算机,而不是从键盘),然后我会按键盘上的任何键通过Console.ReadLine(),并且GetResultPIN()能够从 PIN Pad 获取我的 PIN 码.....整个程序现在可以工作了,它没有客户准备好,因为它非常波涛汹涌,由于我添加而不会流动Console.ReadLine()......

所以理想情况下,所有的方法都会一起流动。一旦设备打开,RequestPIN()应该在PIN Pad屏幕上显示询问PIN号码,有人可以在PIN Pad上键入并按Enter键,它自然会流入GetResultPIN()并读取结果,然后在控制台上打印PIN。 .`

或者

如果此人没有输入 PIN 码,设备将等待 30 秒,然后直接GetResultPIN()在控制台上打印出“0000”

我已经查看了踩踏和委托,但不知道在这种情况下如何使用它们....谢谢!

参考: RequestPin() 和 GetResultPIN 如下所列:

mIPAD.requestPIN(waitTime, pinMsg, minLen, maxLen, tone, option, ",");
//This function wraps device command 0x04.  
//It directs the device to prompt the user to enter a PIN 
//by displaying one of five predetermined messages and playing
// a specified sound.  
//The messages on the device’s screen look like the figures below.  
//The event associated with this function is 
//OnPINRequestCompleteEvent. 

waitTime:设备应等待用户开始输入 PIN 的时间

pinMsg:作为用户提示显示的消息,例如“输入 PIN”、“重新输入 PIN”、“验证 PIN”等

minLen 和 maxLen:PIN 的最小长度和最大长度

音调:提示音选项

选项:验证 PIN,不验证 PIN,ISO0 格式,ISO3 格式

输出为:整数,0:成功,非零:错误

    public void GetResultPIN()
    {
        StringBuilder sb = new StringBuilder();
        sb.Append(mIPAD.pin.KSN); 
               // Key Serial Number: 
               //a given number from the device, unique for each device
        sb.Append("," + mIPAD.pin.EPB);
               // EPB: encryption of PIN after Dubpt TripleDES,
               // essentially, EPB is PIN
        sb.Append("," + mIPAD.getStatusCode());
               //status code: Zero is good/done
               //             None-Zero is Error
        sb.Append("\r\n");
        result = sb.ToString();
    }

基本上,GetResultPIN() 返回一串随机码,例如: 9A00030000047A2000AB,AD781711481B08A2,0当 PIN 成功时。如果引脚输入部分被跳过,它将返回,,0.

4

4 回答 4

2

真的很难知道这是否会在没有硬件的情况下工作......

这是我设想它的工作方式:

    static void Main()
    {
        OpenDevice();
        RequestPIN();
        if (GetResultPIN())
        {
            // do something with the PIN:
            var pin = mIPAD.pin.EPB;

            // ...

        }
        else
        {
            Console.WriteLine("0000");
        }
    }

    public static bool GetResultPIN()
    {
        TimeSpan timeout = TimeSpan.FromSeconds(30);
        System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch();
        SW.Start();
        while (mIPAD.getStatusCode() != 0 && SW.Elapsed < timeout)
        {
            System.Threading.Thread.Sleep(50); // small call to prevent CPU usage ramping to 100%
        }
        return (mIPAD.getStatusCode() == 0);
    }
于 2015-07-29T21:27:38.443 回答
1

您可以将您的 api 重写为:

  • 使GetResultPIN()返回值
  • 使用这个值作为输入ConsolePrintOutPIN()

GetResultPIN你需要做一个任务来读取你的密码并等待它。

请参阅:https ://msdn.microsoft.com/en-us/library/dd537610(v=vs.110).aspx

你可以这样做:

public string GetResultPIN()
{
    StringBuilder sb = new StringBuilder();
    sb.Append(mIPAD.pin.KSN); 
           // Key Serial Number: 
           //a given number from the device, unique for each device
    sb.Append("," + mIPAD.pin.EPB);
           // EPB: encryption of PIN after Dubpt TripleDES,
           // essentially, EPB is PIN
    sb.Append("," + mIPAD.getStatusCode());
           //status code: Zero is good/done
           //             None-Zero is Error
    sb.Append("\r\n");
    Thread.Sleep(20*1000);  // it is in milliseconds
    return sb.ToString();
}
于 2015-07-28T07:12:01.167 回答
0

啊,我想通了。我基本上在这里使用线程。主要流程是OpenDevice()->RequestPIN()->Thread(()=>CheckOpStatus(getResultPIN)) -> Thread.Start()。在线程中,设置了一个循环以每半秒检查一次是什么OpStatus。根据我之前的帖子,OpStatus是 PIN Pad 的输出参数,zero- success; non-zero: failure. 也就是说,循环将继续进行,直到其中一个bool condition_WithinWaitTimebool condition_NoKeyEvent中断。爆发后,调用getResultPIN等....

这是我的源代码,因为 PIN 输入是我的功能之一,其余在编程方面具有非常相似的行为(请求->手动操作->反馈),因此我还包含了一个委托变量来表示所有功能(卡刷卡,PIN,签名bla bla)。

    static void Main(string[] args)
    {
        OpenDevice();
        EventGetPIN();

    }
    static void EventGetPIN()
    {
        myDel getResult = new myDel(GetResultPIN);
        Thread thread1 = new Thread(() => CheckOpStatus(getResult));

        myDel requestDel = new myDel(RequestPIN); requestDel();
        thread1.Start();
    }
    static void CheckOpStatus(Delegate getResult)
    {
        int count = 0;
        int checkingPeriod = 500;
        int totalWaitTime = waitTime * 1000 + offsetTime;
        string OpStatus;
        string ksnStart = mIPAD.getKSN();
        string ksn = ksnStart;
        bool condition_WithinWaitTime = true;
        bool condition_NoKeyEvent = true;
        while (condition_WithinWaitTime & condition_NoKeyEvent)
        {
            count++;
            OpStatus = mIPAD.getStatusCode().ToString();
            ksn = mIPAD.getKSN();
            //Console.WriteLine(OpStatus);
            condition_WithinWaitTime = (count * checkingPeriod) < totalWaitTime;
            condition_NoKeyEvent = (ksn == ksnStart);
            Thread.Sleep(checkingPeriod);
        }

        getResult.DynamicInvoke();
    }
于 2015-07-30T13:23:07.630 回答
0

感谢您发布...解决方案仍然不理想....我还对该功能进行了更多测试RequestPIN()。我有以下四种情况:

  1. 用户在 PINwaitTime熄灭之前完成键入 PIN。 onPINRequestComplete : OpStatus:0 KSN:9A00030000047A2000C8 EPB:39DED176D3EA40B9 ..............................
  2. waitTime外出时,用户未完成输入 PIN 码。
    onPINRequestComplete : OpStatus:2 KSN:00000000000000000000 EPB:0000000000000000 ..............................

  3. 用户通过按密码键盘上的“取消 X”键取消密码键盘选项。

    onPINRequestComplete : OpStatus:1 KSN:00000000000000000000 EPB:0000000000000000 ..............................

  4. 用户在 waitTime 期间根本没有输入 PIN,然后 waitTime 熄灭。

    onPINRequestComplete : OpStatus:2 KSN:00000000000000000000 EPB:0000000000000000 .............................. 因此,场景 1 和 3 将要求线程立即唤醒,而场景 2 和 4 将要求线程在 waiTime 结束时唤醒。所以在场景2和4中使用Thread.sleep(20*1000)withinGetResultPIN()可以完美地工作。至于1和3,用户必须等待很长时间......

另一方面,我发现了一些关于Event

Car.cs 中

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WaitOnTasksToComplete
{
    class Car
    {
        public event Action OnChange;

        private double speed;
        public double Speed
        {
            get { return speed; }
            set { speed = value;
                if (speed >= 60)
                {
                    if (OnChange != null)
                    {
                        OnChange();
                    }
                }
            }
        }
    }
}

Program.cs 中

using System;

namespace WaitOnTasksToComplete
{
    class Program
    {
        static void Main(string[] args)
        {
            Car c = new Car();
            c.OnChange += C_OnChange;

            c.Speed = 5;
            c.Speed = 55;
            c.Speed = 65;
            c.Speed = 75;

        }

        private static void C_OnChange()
        {
            Console.WriteLine("Event fired: Car goes higher than 60 MPH.");
        }
    }
}

所以,基本上一旦Car.speed跳到60以上,警报就会出现。我正在考虑将条件借入我的情况: Initialize OpStatus = -999。何时OpStatus=0 or 1,继续执行GetResultPIN()PrintMessagePIN()。如果OpStatus=2 or others,请继续等待...

这只是我的想法......仍然不知道如何实现它......任何相关的想法或建议将不胜感激......

于 2015-07-29T13:52:39.097 回答