0

Firstly i developed a simple XML sender that sends xml data from a file to a web server which is coded as a loop therefore one XML file at a time.

Now i want to make it multi threaded which means that i enter lets say 3 file names of the XML files and a thread is created for each file and is sent to the webserver in parallel. Below is my current implementation, Ive tried messing around by adding worker threads here and there. Edit* So the question is how do i mulithread this type of program?

Below is my current implementation:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

namespace XMLSender
{
    class Program
    {
        private static string serverUrl;

        static void Main(string[] args)
        {
            Console.WriteLine("Please enter the URL to send the XML File");
            serverUrl = Console.ReadLine();
            List<Thread> threads = new List<Thread>();
            string fileName = "";
            do
            {
                Console.WriteLine("Please enter the XML File you Wish to send");
                Thread t = new Thread(new ParameterizedThreadStart(send));
                t.Start(fileName = Console.ReadLine());
                threads.Add(t);
            }
            while (fileName != "start"); //Ends if user enters an empty line
            foreach (Thread t in threads)
            {
                t.Join();
            }
        }
        static private void send(object data)
        {
            try
            {
                //ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serverUrl);
                byte[] bytes;

                //Load XML data from document 
                XmlDocument doc = new XmlDocument();
                doc.Load((string)data);
                string xmlcontents = doc.InnerXml;

                //Send XML data to Webserver
                bytes = Encoding.ASCII.GetBytes(xmlcontents);
                request.ContentType = "text/xml; encoding='utf-8'";
                request.ContentLength = bytes.Length;
                request.Method = "POST";
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(bytes, 0, bytes.Length);
                requestStream.Close();

                // Get response from Webserver
                HttpWebResponse response;
                response = (HttpWebResponse)request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                string responseStr = new StreamReader(responseStream).ReadToEnd();
                Console.Write(responseStr + Environment.NewLine);

            }
            catch (Exception e)
            {
                Console.WriteLine("An Error Occured" + Environment.NewLine + e);
                Console.ReadLine();
            }
        }
    }
}
Freon
  • 47
  • 1
  • 11
  • Whats the question? – elyashiv Aug 01 '16 at 15:17
  • The main idea is how do i mulithread the this type of application, ill update it above – Freon Aug 01 '16 at 15:18
  • So what have you attempted in the space of multithreading your current implementation? Can you show code, post errors or issues you ran into? – Bearcat9425 Aug 01 '16 at 15:19
  • Ive taken a look at a couple of example on the MSDN c# multithreading reference, but seeing all the different types of implementation have confused me. Can async be used here aswell ? – Freon Aug 01 '16 at 15:22
  • Actually i may have an idea, ill update the code once i try it out – Freon Aug 01 '16 at 15:28

1 Answers1

1

Try something like this: For every file you entered, a new thread gets created and uploads the file ("..." indicates code that does not have changed). The static variable serverUrl is not a good way, of course, but it serves it purpose here. The method used can also be non-static. You can use any way to exit the Loop creating the threads, in this case the user must enter an empty line

To wait until all threads have finished, use somethign like Thread.Join(), and store all created threads in a list

List<Thread> threads = new List<Threads>();
...
threads.add(new Thread(...));
...
foreach (Thread t in threads) t.Join();

Here the changed code

class Program
{
    private static string serverUrl;

    static void Main(string[] args)
    {
        Console.WriteLine("Please enter the URL to send the XML File");
        serverUrl = Console.ReadLine();

        string fileName = "";
        do
        {
            Console.WriteLine("Please enter the XML File you Wish to send");
            Thread t = new Thread(new ParameterizedThreadStart(send));
            fileName = Console.ReadLine();
            if(fileName != "")
                t.Start();
        }
while (fileName != ""); //Ends if user enters an empty line
    }

    static private void send(object url)
    {
        try
        {
            //ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serverUrl);
            byte[] bytes;
            //Load XML data from document 
            XmlDocument doc = new XmlDocument();
            doc.Load((string)url);
            string xmlcontents = doc.InnerXml;
             ...
            Console.Write(responseStr + Environment.NewLine);
        }
        catch (Exception e)
        {
            Console.WriteLine("An Error Occured" + Environment.NewLine + e);
            Console.ReadLine();
        }
    }
}
  • ill check it out and ill get back to you. – Freon Aug 01 '16 at 15:49
  • I highly suggest you look at Task, or async and await over thread class, a thread is not a lightweight object and for the load this applications appears to be doing a Task would be better suited I believe. There is a nice blog post from Slaks on this http://blog.slaks.net/2013-10-11/threads-vs-tasks/ – Bearcat9425 Aug 01 '16 at 15:52
  • This was more a hint to the right direction, but i will check out this resource and see with what i can come up better than currently – technikfischer Aug 01 '16 at 15:57
  • I deleted the previous comments since there was a minor mistake when copying the code, So i ran the code which allowed me to enter the url and then the xml file but it sends instantly to the webserver rather than writing all the files and then sending them all across. – Freon Aug 01 '16 at 16:23
  • So the idea is to enter multiple files and wait until "" is pressed and and all of them are sent across at the same time?. So i guess Thread Join would be the thing here. – Freon Aug 01 '16 at 16:43
  • You can save all entered files to a list. After entering all of them, just cretae all threads from this list, and start them at the same time. Thread.Join () for each will wait until all have ended – technikfischer Aug 01 '16 at 17:39
  • Hey, ive updated the code to include the list but it currently still responds before all files have been chosen. – Freon Aug 02 '16 at 08:35
  • Since this is an different question from the original which you answered, ill create another post. – Freon Aug 02 '16 at 09:13
  • Update: I think the static url method uses the same connection for the webcreate therefore only one XML file is sent, is it possible to change that so a new webcreate is created for each thread? – Freon Aug 02 '16 at 12:03
  • That should not be a thing. [This answer](http://stackoverflow.com/a/3037690/6201216) states that declared variables are isolated, therefore the WebRequests are too – technikfischer Aug 02 '16 at 14:05