?
Solved

A quick "fix" is place "Application.DoEvents();"

Posted on 2011-10-22
10
Medium Priority
?
305 Views
Last Modified: 2012-05-12
My problem is with the event.
I have 6 devices that need to access it in one second for data collection.
It should work like this:
Pressed the button that will access the devices automatically every 10 seconds.
Let's call a timer with 10 seconds INTERVAL.

The application sends the command ID01 to the serial port and awaiting a response.

If do not answer or the answer that comes is different from what I hope, that Reeves command.
In the fifth time, warns that not received the response.

So changes to ID01, and repeat the steps above.
If has answer and what is expected.
So changes to ID02 and repeat the above steps.

Thus even ID06.

Expect the cycle of 10 seconds and restarts the cycle.

private void button10_Click(object sender, EventArgs e)
        {            
            textBox2.Clear();
            CommPort com = CommPort.Instance;

            for (int i = 0; i <= 6; i++)
            {
            for (int x = 0;x <= 5;x++)
                {
                string vstr = "ID0" + i.ToString();
                string s_ID_compare = "0"+i.ToString();
                vstr = ConvertEscapeSequences(vstr);
                com.Send(vstr);
                if(returned data = s_ID_compare)
                    {
                    ..................
                        x= 6;
                    }

                }
            }
        }

Open in new window

0
Comment
Question by:ocaccy
10 Comments
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 500 total points
ID: 37012616
What exactly do you need help with? Getting rid of Application.DoEvents or writing the logic for the loop?
0
 

Author Comment

by:ocaccy
ID: 37013039
Both.
I have the button code above.
And the code below.
I know there are errors in both: logic and code; Why am I suffering from it.

What I need is this:

The method should run automatically at intervals of 10 seconds.
// We have 6 devices: ID01, ID02, ID03, ID04, ID05, ID06
Send the command to CommPort ID01.
Returned?
Yes! These data and stores it in variables to write to. CSV file after ID06 is checked. Next.
No! 1 second interval. Resends the command ID01.
Repeat this cycle 5 times, If it returns! He did not return the fifth time. Error Alert. Stores this error alert in variable. Next.
 
We repeat the above steps with the ID02, ID03, ID04, ID05, ID06 and save the data in a file  CSV, and location of the data ID that did not return a warning and Error Alert.
Clear the variables and restart the cycle in ID01.

I need a error code for any problems occurs in this method too.

Regards,
ocaccy
/// <summary>
        /// Handle data received event from serial port.
        /// </summary>
        /// <param name="data">incoming data</param>
        public void OnDataReceived(string dataIn)
        {
            //Handle multi-threading
            if (InvokeRequired)
            {
                Invoke(new StringDelegate(OnDataReceived), new object[] { dataIn });
                return;
            }

            // pause scrolling to speed up output of multiple lines
            bool saveScrolling = scrolling;
            scrolling = false;

            // if we detect a line terminator, add line to output
            int index;
            while (dataIn.Length > 0 &&
                ((index = dataIn.IndexOf("\r")) != -1 ||
                (index = dataIn.IndexOf("\n")) != -1))
            {
                String StringIn = dataIn.Substring(0, index);
                dataIn = dataIn.Remove(0, index + 1);

                logFile_writeLine(AddData(StringIn).Str);
                logFile_writeLine1(AddData(StringIn).Str);
                partialLine = null;	// terminate partial line
            }

            // if we have data remaining, add a partial line
            if (dataIn.Length > 0)
            {
                Thread.Sleep(25);
                partialLine = AddData(dataIn);
            }

            // restore scrolling
            scrolling = saveScrolling;
            outputList_Scroll();
            listBox1_Scroll();
        }

        /// <summary>
        /// Update the connection status
        /// </summary>
        public void OnStatusChanged(string status)
        {
            //Handle multi-threading
            if (InvokeRequired)
            {
                Invoke(new StringDelegate(OnStatusChanged), new object[] { status });
                return;
            }

            textBox1.Text = status;
        }

        #endregion

Open in new window

public int cnt_Indx = 0;
        /// <summary>
        /// output string to log file soIDlog
        /// </summary>
        /// <param name="stringOut">string to output</param>
        public void logFile_writeLine1(string stringOut)
        {
            string SS_id01 ="";
            if (stringOut.Contains("01") || stringOut.Contains("02") || stringOut.Contains("03") || stringOut.Contains("04") || stringOut.Contains("05") || stringOut.Contains("06"))
            {
                Stream myStream = File.Open("F:/USUARIOS/dtp2/SAIDAX/soIDlog.CSV",
                        FileMode.Append, FileAccess.Write, FileShare.Read);
                if (myStream != null)
                {
                    //StreamWriter myWriter = new StreamWriter(myStream, Encoding.UTF8);
                    //myWriter.WriteLine(stringOut);
                    //myWriter.Close();
                    ///////////////////////////////////////////////////////////////////////////////////////////////////// string[] a_stringout = stringOut.Split(",");
                    textBox2.AppendText(stringOut.Trim().Substring(0, 4)); // mudei para 4 de 16
                    listBox1.Items.Add(stringOut.Trim().Substring(1, 20));

                    #region Confere se os ID foram recebidos

                    if (textBox2.Text.Contains("01"))
                    {
                        lbl_testx.Text = "ID01";
                        lbl_CkID01.Text = "ID01";
                    }

                    if (textBox2.Text.Contains("02"))
                    {
                        lbl_testx.Text = "ID02";
                        lbl_CkID02.Text = "ID02";
                    }

                    if (textBox2.Text.Contains("03"))
                    {
                        lbl_testx.Text = "ID03";
                        lbl_CkID03.Text = "ID03";
                    }

                    if (textBox2.Text.Contains("04"))
                    {
                        lbl_testx.Text = "ID04";
                        lbl_CkID04.Text = "ID04";
                    }

                    if (textBox2.Text.Contains("05"))
                    {
                        lbl_testx.Text = "ID05";
                        lbl_CkID05.Text = "ID05";
                    }

                    if (textBox2.Text.Contains("06"))
                    {
                        lbl_testx.Text = "ID06";
                        lbl_CkID06.Text = "ID06";
                    }

                    #endregion

                    string s_ID = stringOut.Trim().Substring(1, 2);

                    

                    #region se tiver s_ID == 01
                    
                    if (s_ID == "01")
                        
                    {
                        gB_id01.Visible = true;

                        SS_id01 = s_ID + "," + lbl_id01_02mm.Text + "," + lbl_id01_07mm.Text + "," + lbl_id01_10mm.Text;
                        lbl_id01_02mm.Text = stringOut.Trim().Substring(4, 5);
                        lbl_id01_07mm.Text = stringOut.Trim().Substring(10, 5);
                        lbl_id01_10mm.Text = stringOut.Trim().Substring(16, 5);
                        label_id01.Text = SS_id01;

                        a_i_id_01[cnt_Indx, 0] = stringOut.Trim().Substring(4, 5);
                        a_i_id_01[cnt_Indx, 1] = stringOut.Trim().Substring(10, 5);
                        a_i_id_01[cnt_Indx, 2] = stringOut.Trim().Substring(16, 5);
                        a_i_id_01[cnt_Indx, 3] = "1";

                        #region This is clear in the future. lança os dados dividos em variaveis para os calculos.
                        ///<sumary>
                        ///vamos tirar isso depois
                        ///
                        double dWid01_c6 = 0;
                        string dWid01_d6 = DateTime.Now.ToString("HH:mm:ss");
                        string dWid01_id_e6 = "ID01";
                        string dWid01_2m_f6 = lbl_id01_02mm.Text;
                        string dWid01_7m_g6 = lbl_id01_07mm.Text;
                        string dWid01_10m_h6 = lbl_id01_10mm.Text;

                        lbl_dWid01_c6.Text = dWid01_c6.ToString();
                        lbl_dWid01_d6.Text = dWid01_d6.ToString();
                        lbl_dWid01_e6.Text = dWid01_id_e6;
                        lbl_dWid01_f6.Text = dWid01_2m_f6.ToString();
                        lbl_dWid01_g6.Text = dWid01_7m_g6.ToString();
                        lbl_dWid01_h6.Text = dWid01_10m_h6.ToString();

                        #endregion

                        StreamWriter myWriter = new StreamWriter(myStream, Encoding.UTF8);
                        myWriter.WriteLine(DateTime.Now.ToLongDateString() + "," + DateTime.Now.ToLongTimeString() + "," + "ID01 ," + lbl_id01_02mm.Text + "," + lbl_id01_07mm.Text + "," + lbl_id01_10mm.Text);
                        myWriter.Close();
                    }

                    #endregion

                    #region se tiver s_ID == 02

                    if (s_ID == "02")
                    {
                        gB_id02.Visible = true;

                        string SS_id2 = s_ID + "," + lbl_id02_02mm.Text + "," + lbl_id02_07mm.Text + "," + lbl_id02_10mm.Text;
                        lbl_id02_02mm.Text = stringOut.Trim().Substring(4, 5);
                        lbl_id02_07mm.Text = stringOut.Trim().Substring(10, 5);
                        lbl_id02_10mm.Text = stringOut.Trim().Substring(16, 5);
                        label_id02.Text = SS_id2;

                        a_i_id_02[cnt_Indx, 0] = stringOut.Trim().Substring(4, 5);
                        a_i_id_02[cnt_Indx, 1] = stringOut.Trim().Substring(10, 5);
                        a_i_id_02[cnt_Indx, 2] = stringOut.Trim().Substring(16, 5);
                        a_i_id_02[cnt_Indx, 3] = "1";


                        #region This is clear in the future. lança os dados dividos em variaveis para os calculos.

                        double dWid02_c6 = 0; string dWid02_d6 = DateTime.Now.ToString("HH:mm:ss");
                        string dWid02_id_e6 = "ID02"; string dWid02_2m_f6 = lbl_id02_02mm.Text;
                        string dWid02_7m_g6 = lbl_id02_07mm.Text; string dWid02_10m_h6 = lbl_id02_10mm.Text;
                        lbl_dWid02_c6.Text = dWid02_c6.ToString();
                        lbl_dWid02_d6.Text = dWid02_d6.ToString();
                        lbl_dWid02_e6.Text = dWid02_id_e6;
                        lbl_dWid02_f6.Text = dWid02_2m_f6.ToString();
                        lbl_dWid02_g6.Text = dWid02_7m_g6.ToString();
                        lbl_dWid02_h6.Text = dWid02_10m_h6.ToString();
                        #endregion

                        StreamWriter myWriter = new StreamWriter(myStream, Encoding.UTF8);
                        myWriter.WriteLine(DateTime.Now.ToLongDateString() + "," + DateTime.Now.ToLongTimeString() + "," + label_id02.Text);
                        myWriter.Close();
                    }

                    #endregion

                    #region se tiver s_ID == 03

                    if (s_ID == "03")
                    {
                        gB_id03.Visible = true;

                        string SS_id3 = s_ID + "," + lbl_id03_02mm.Text + "," + lbl_id03_07mm.Text + "," + lbl_id03_10mm.Text;
                        lbl_id03_02mm.Text = stringOut.Trim().Substring(4, 5);
                        lbl_id03_07mm.Text = stringOut.Trim().Substring(10, 5);
                        lbl_id03_10mm.Text = stringOut.Trim().Substring(16, 5);
                        label_id03.Text = SS_id3;

                        a_i_id_03[cnt_Indx, 0] = stringOut.Trim().Substring(4, 5);
                        a_i_id_03[cnt_Indx, 1] = stringOut.Trim().Substring(10, 5);
                        a_i_id_03[cnt_Indx, 2] = stringOut.Trim().Substring(16, 5);
                        a_i_id_03[cnt_Indx, 3] = "1";

                        #region This is clear in the future. lança os dados dividos em variaveis para os calculos.
                        double dWid03_c6 = 0; string dWid03_d6 = DateTime.Now.ToString("HH:mm:ss"); string dWid03_id_e6 = "ID03"; string dWid03_2m_f6 = lbl_id03_02mm.Text; string dWid03_7m_g6 = lbl_id03_07mm.Text; string dWid03_10m_h6 = lbl_id03_10mm.Text;
                        lbl_dWid03_c6.Text = dWid03_c6.ToString();
                        lbl_dWid03_d6.Text = dWid03_d6.ToString();
                        lbl_dWid03_e6.Text = dWid03_id_e6;
                        lbl_dWid03_f6.Text = dWid03_2m_f6.ToString();
                        lbl_dWid03_g6.Text = dWid03_7m_g6.ToString();
                        lbl_dWid03_h6.Text = dWid03_10m_h6.ToString();
                        #endregion

                        StreamWriter myWriter = new StreamWriter(myStream, Encoding.UTF8);
                        myWriter.WriteLine(DateTime.Now.ToLongDateString() + "," + DateTime.Now.ToLongTimeString() + "," + label_id03.Text);
                        myWriter.Close();
                    }

                    #endregion

                    #region se tiver s_ID == 04

                    if (s_ID == "04")
                    {
                        gB_id04.Visible = true;

                        string SS_id4 = s_ID + "," + lbl_id04_02mm.Text + "," + lbl_id04_07mm.Text + "," + lbl_id04_10mm.Text;
                        lbl_id04_02mm.Text = stringOut.Trim().Substring(4, 5);
                        lbl_id04_07mm.Text = stringOut.Trim().Substring(10, 5);
                        lbl_id04_10mm.Text = stringOut.Trim().Substring(16, 5);
                        label_id04.Text = SS_id4;

                        a_i_id_04[cnt_Indx, 0] = stringOut.Trim().Substring(4, 5);
                        a_i_id_04[cnt_Indx, 1] = stringOut.Trim().Substring(10, 5);
                        a_i_id_04[cnt_Indx, 2] = stringOut.Trim().Substring(16, 5);
                        a_i_id_04[cnt_Indx, 3] = "1";

                        #region This is clear in the future. lança os dados dividos em variaveis para os calculos.
                        double dWid04_c6 = 0; string dWid04_d6 = DateTime.Now.ToString("HH:mm:ss"); string dWid04_id_e6 = "ID04"; string dWid04_2m_f6 = lbl_id04_02mm.Text; string dWid04_7m_g6 = lbl_id04_07mm.Text; string dWid04_10m_h6 = lbl_id04_10mm.Text;
                        lbl_dWid04_c6.Text = dWid04_c6.ToString();
                        lbl_dWid04_d6.Text = dWid04_d6.ToString();
                        lbl_dWid04_e6.Text = dWid04_id_e6;
                        lbl_dWid04_f6.Text = dWid04_2m_f6.ToString();
                        lbl_dWid04_g6.Text = dWid04_7m_g6.ToString();
                        lbl_dWid04_h6.Text = dWid04_10m_h6.ToString();
                        #endregion

                        StreamWriter myWriter = new StreamWriter(myStream, Encoding.UTF8);
                        myWriter.WriteLine(DateTime.Now.ToLongDateString() + "," + DateTime.Now.ToLongTimeString() + "," + label_id04.Text);
                        myWriter.Close();
                    }

                    #endregion

                    #region se tiver s_ID == 05

                    if (s_ID == "05")
                    {
                        gB_id05.Visible = true;

                        string SS_id5 = s_ID + "," + lbl_id05_02mm.Text + "," + lbl_id05_07mm.Text + "," + lbl_id05_10mm.Text;
                        lbl_id05_02mm.Text = stringOut.Trim().Substring(4, 5);
                        lbl_id05_07mm.Text = stringOut.Trim().Substring(10, 5);
                        lbl_id05_10mm.Text = stringOut.Trim().Substring(16, 5);
                        label_id05.Text = SS_id5;

                        a_i_id_05[cnt_Indx, 0] = stringOut.Trim().Substring(4, 5);
                        a_i_id_05[cnt_Indx, 1] = stringOut.Trim().Substring(10, 5);
                        a_i_id_05[cnt_Indx, 2] = stringOut.Trim().Substring(16, 5);
                        a_i_id_05[cnt_Indx, 3] = "1";

                        #region This is clear in the future. lança os dados dividos em variaveis para os calculos.
                        double dWid05_c6 = 0; string dWid05_d6 = DateTime.Now.ToString("HH:mm:ss"); string dWid05_id_e6 = "ID05"; string dWid05_2m_f6 = lbl_id05_02mm.Text; string dWid05_7m_g6 = lbl_id05_07mm.Text; string dWid05_10m_h6 = lbl_id05_10mm.Text;
                        lbl_dWid05_c6.Text = dWid05_c6.ToString();
                        lbl_dWid05_d6.Text = dWid05_d6.ToString();
                        lbl_dWid05_e6.Text = dWid05_id_e6;
                        lbl_dWid05_f6.Text = dWid05_2m_f6.ToString();
                        lbl_dWid05_g6.Text = dWid05_7m_g6.ToString();
                        lbl_dWid05_h6.Text = dWid05_10m_h6.ToString();
                        #endregion


                        StreamWriter myWriter = new StreamWriter(myStream, Encoding.UTF8);
                        myWriter.WriteLine(DateTime.Now.ToLongDateString() + "," + DateTime.Now.ToLongTimeString() + "," + label_id05.Text);
                        myWriter.Close();
                    }

                    #endregion

                    #region se tiver s_ID == 06

                    if (s_ID == "06")
                    {
                        gB_id06.Visible = true;

                        string SS_id6 = s_ID + "," + lbl_id06_02mm.Text + "," + lbl_id06_07mm.Text + "," + lbl_id06_10mm.Text;
                        lbl_id06_02mm.Text = stringOut.Trim().Substring(4, 5);
                        lbl_id06_07mm.Text = stringOut.Trim().Substring(10, 5);
                        lbl_id06_10mm.Text = stringOut.Trim().Substring(16, 5);
                        label_id06.Text = SS_id6;

                        a_i_id_06[cnt_Indx, 0] = stringOut.Trim().Substring(4, 5);
                        a_i_id_06[cnt_Indx, 1] = stringOut.Trim().Substring(10, 5);
                        a_i_id_06[cnt_Indx, 2] = stringOut.Trim().Substring(16, 5);
                        a_i_id_06[cnt_Indx, 3] = "1";

                        #region This is clear in the future. lança os dados dividos em variaveis para os calculos.
                        double dWid06_c6 = 0; string dWid06_d6 = DateTime.Now.ToString("HH:mm:ss"); string dWid06_id_e6 = "ID06"; string dWid06_2m_f6 = lbl_id06_02mm.Text; string dWid06_7m_g6 = lbl_id06_07mm.Text; string dWid06_10m_h6 = lbl_id06_10mm.Text;
                        lbl_dWid06_c6.Text = dWid06_c6.ToString();
                        lbl_dWid06_d6.Text = dWid06_d6.ToString();
                        lbl_dWid06_e6.Text = dWid06_id_e6;
                        lbl_dWid06_f6.Text = dWid06_2m_f6.ToString();
                        lbl_dWid06_g6.Text = dWid06_7m_g6.ToString();
                        lbl_dWid06_h6.Text = dWid06_10m_h6.ToString();
                        #endregion


                        StreamWriter myWriter = new StreamWriter(myStream, Encoding.UTF8);
                        myWriter.WriteLine(DateTime.Now.ToLongDateString() + "," + DateTime.Now.ToLongTimeString() + "," + label_id06.Text);
                        myWriter.Close();
                    }

                    #endregion

                    cnt_Indx++;

                    listBox1.Items.Clear();


                }
            }
        }

Open in new window

0
 
LVL 143

Assisted Solution

by:Guy Hengel [angelIII / a3]
Guy Hengel [angelIII / a3] earned 1000 total points
ID: 37017701
"waiting" while keeping the application responsive should be done with a timer object, in this case, "timed" every 1 second.

and in that timer event, you need to find out what to do next, what was done last etc ...

so, you could "request" to the 6 ID more or less "in parallel", and check/wait for each one individually, and retry each one as needed, until either "timeout" or all done.

to implement this with "less code", you need to implement a class which holds the data for a CommPort, and create 6 variables off that class (in any array for example...). this class needs to hold the information if it's done, error status, reply data etc what is needed.

in your timer event, you just "loop" over the 6 com part objects, if there is 1 to do, do it, and wait for the next timer.
if all are "done" (or at least 1 failed) save to CSV file as needed, and "reset" if needed ...

hope this helps ...
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:ocaccy
ID: 37018069
Angellll,
You help me to write the routine or method or class as you described above.
Why is the code I developed, is defective.

Regards,
ocaccy
0
 
LVL 143

Assisted Solution

by:Guy Hengel [angelIII / a3]
Guy Hengel [angelIII / a3] earned 1000 total points
ID: 37033160
note sure where it is defective ...
and I cannot write the code for you, just give guidance about how to do it.
0
 

Author Comment

by:ocaccy
ID: 37034594
Ok.

I understand.

I reanalyzed the code and return to continue.
0
 

Author Comment

by:ocaccy
ID: 37124112
The method with the command to the serial port is below.
But I can not solve this little problem.
In 10 hours of testing.
Not received data 3 times. This is unacceptable for my application.
How to solve?
private void timer_01_Tick(object sender, EventArgs e)
        {

            #region TRABALHA ID01
            this.dataReceived = false;
            string s_ID01_c = "id01";
            CommPort com = CommPort.Instance;
            s_ID01_c = ConvertEscapeSequences(s_ID01_c); ;
            com.Send(s_ID01_c);

            // Wait for data
            DateTime start = DateTime.UtcNow;
            while (!this.dataReceived)
            {
                // Timeout if has not completed in 5 seconds
                if (DateTime.UtcNow.Subtract(start).TotalSeconds > 5)
                    throw new TimeoutException();

                //Thread.Sleep(10);
                Application.DoEvents();
            }

            //Thread.Sleep(150); // Dorme por 150 segundos
            //com.Send(s_ID01_c);
            timer_02.Enabled = true;
            timer_01.Enabled = false;
            #endregion

        }

Open in new window

0
 
LVL 86

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 500 total points
ID: 37124421
I don't see how the code above could prevent you from receiving the message.  The problem might be somewhere else or it could just be an occasional hiccup device.
0
 

Author Comment

by:ocaccy
ID: 37174431
We had a problem of not receiving data, and receive duplicate data from the serial port with 6 devices RS485/USB, connected to the pc by a converter USB/RS485.

We solve the problem.

I used the code below.

Best Regards,
ocaccy.
// timer-10 interval= 10000ms
// timer-01 interval= 200ms
// timer-02 interval= 200ms
// timer-03 interval= 200ms
// timer-04 interval= 200ms
// timer-05 interval= 200ms
// timer-06 interval= 200ms

 private void GetData_Click(object sender, EventArgs e)
        {
            timer_10.Enabled = true;
        }

 private void timer_10_Tick(object sender, EventArgs e)
        {
            timer_01.Enabled = true;
        }


#region timer_01_Tick 
private void timer_01_Tick(object sender, EventArgs e)
        {
            #region WORKING ID01
            this.dataReceived = false;
            send_t = 0;
            free1.Enabled = true;
            #endregion
        }

private void free1_Tick(object sender, EventArgs e)
       {
            if (send_t == 3)
            {
                this.dataReceived = true;
            }
            if (this.dataReceived == false)
            {
                string s_ID01_c = "id01";
                CommPort com = CommPort.Instance;
                s_ID01_c = ConvertEscapeSequences(s_ID01_c);
                com.Send(s_ID01_c);
                send_t = send_t + 1;

            }
            else
            {
                free1.Enabled = false;
                timer_02.Enabled = true;
                timer_01.Enabled = false;
            }
        }
        #endregion

// After ends 01, chage to 02, to 03...........

Open in new window

0
 

Author Closing Comment

by:ocaccy
ID: 37174451
Thank you.
Yall do not give me a code, but show me the way.

Best Regards,
ocaccy
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction A frequently used term in Object-Oriented design is "SOLID" which is a mnemonic acronym that covers five principles of OO design.  These principles do not stand alone; there is interplay among them.  And they are not laws, merely princ…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question