C#winforms和线程

时间:2012-04-23 09:26:18

标签: c# winforms multithreading

我有一个按钮“start”赢了表单,当我点击它时,开始逐行读取.txt文件并将请求发送到服务器。 我的问题是 - 当我点击“开始”从文件中读取50行然后停止并等待另一次单击“开始”时,我该怎么做? 线程是唯一可行的解​​决方案吗? 这是我的按钮:

private void btnStart_Click(object sender, EventArgs e)
    {
        List<string> List = LoadFromFile("FILE");
        int dialogid = 0;
        foreach (string g in List)
        {
            dialogid++;
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("number", g);
            parameters.Add("dialogid", dialogid.ToString());

            if (InvokeService(this.tbWebServiceURL.Text, parameters) == false)
            {
                MessageBox.Show("ERROR!", "ERROR");
                return;
            }
        }

这是我的帖子请求:

private bool InvokeService(string ServiceURL, Dictionary<string, string> parameters)
    {          
        try
        {           
            string data = "";
            int cnt = 0;

            byte[] dataStream = Encoding.UTF8.GetBytes(data);
            WebRequest webRequest = WebRequest.Create("URL");
            webRequest.Method = "POST";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.ContentLength = dataStream.Length;

            foreach (KeyValuePair<string, string> kvk in parameters)
            {
                webRequest.Headers.Add(kvk.Key, kvk.Value);
            }

            WebResponse response = webRequest.GetResponse();
            Stream dataStreamResponse = response.GetResponseStream();
            StreamReader reader = new StreamReader(dataStreamResponse);
            string responseFromServer = reader.ReadToEnd();
            Console.WriteLine(responseFromServer);
            reader.Close();
            dataStreamResponse.Close();
            response.Close();

这里最重要的是没有读取整个文件,只需点击“开始”。必须等待另一个“开始”。读取50行并等待单击“开始”以读取第二行50行。 希望现在更清楚了。

3 个答案:

答案 0 :(得分:1)

BackgroundWorker大纲 - 未经测试:

        private void button1_Click(object sender, EventArgs e)
        {
            if (fileReader == null) fileReader = new StreamReader("File");
            string thisLine;
            netJob bwClass = new netJob(this.tbWebServiceURL.Text);
            for (int i = 0; i < 50; i++)
            {
                thisLine = fileReader.ReadLine();
                if(thisLine=="")break;
                dialogid++;
                Dictionary<string, string> newDict = new Dictionary<string, string>();
                newDict.Add("number", thisLine);
                newDict.Add("dialogid", dialogid.ToString());
                bwClass.Fparams.Add(newDict);
            }
            backgroundWorker1.RunWorkerAsync(bwClass);
        }



    class netJob
    {
        private string FURL;
        public List< Dictionary<string, string> > Fparams;
        private Dictionary<string, string> FthisParam;
        public string errorMess;
        public string responseFromServer;
        public List<string> responsesFromServer;
        public netJob(String URL)
        {
            FURL = URL;
            Fparams= new List< Dictionary<string, string> >();
            responsesFromServer=new List<string>();
            errorMess = "";
        }
        public void run()
        {
            foreach (Dictionary<string, string> thisDict in Fparams)
            {
                InvokeService(FURL, thisDict);
                if (errorMess == "") responsesFromServer.Add(responseFromServer);
                else
                {
                    responsesFromServer.Add(errorMess);
                }

            }
        }

        private bool InvokeService(string ServiceURL, Dictionary<string, string> parameters)
        {
            try
            {
                string data = "";
                byte[] dataStream = Encoding.UTF8.GetBytes(data);
                WebRequest webRequest = WebRequest.Create("URL");
                webRequest.Method = "POST";
                webRequest.ContentType = "application/x-www-form-urlencoded";
                webRequest.ContentLength = dataStream.Length;

                foreach (KeyValuePair<string, string> kvk in parameters)
                {
                    webRequest.Headers.Add(kvk.Key, kvk.Value);
                }

                WebResponse response = webRequest.GetResponse();
                Stream dataStreamResponse = response.GetResponseStream();
                StreamReader reader = new StreamReader(dataStreamResponse);
                responseFromServer = reader.ReadToEnd();
                reader.Close();
                dataStreamResponse.Close();
                response.Close();
            }
            catch (Exception e)
            {
                errorMess = e.Message;
            }
        }
    }
}

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            netJob thisJob = e.Argument as netJob;
            thisJob.run();
        }


        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
                netJob thisJob = e.Result as netJob;
                foreach (string thisResponse in thisJob.responsesFromServer)
                {
                    Console.WriteLine(thisResponse);
                }
        }

答案 1 :(得分:0)

不确定您是否需要线程。只有一个reasone - 处理50行是慢操作,你不会冻结此时的UI,然后是 - 你应该将这项工作委托给工作线程,而不是在UI线程中执行它,否则你应该没有像简单的解决方案那样如下所示:

bool isInProgress = false;

private void OnStartButtonClick(object sender, EventArgs args)
{
  // avoid multiple clicks mess
  if (isInProgress) 
  {  
    return;
  }

  try
  {
     startButton.isEnabled = false;
     isInProgress = true;    
     int counter = 50;

     while (counter-- > 0)
     {
        var singleLine = File.ReadLine(path); 
        var message = CreateMessageFromLine(singleLine);
        transport.PostMessageToServer(message);
     }
   }
   finally
   {
       isInProgress = false;
       startButton.isEnabled = true;
   }
}

答案 2 :(得分:0)

我会这样做:

private void StartButton_Click(object sender, EventArgs args)
{
    StartButton.Enabled = false;
    try
    {
        for (int i = 0; i < 50; i++)
        {
            string line = file.ReadLine();
            //Send to server
        }
    }
    finally
    {
        StartButton.Enabled = true;
    }
}

在读取50行时禁用开始按钮,然后启用它以便您可以读取另外50行。

一次读取50行足够快,因此您不需要线程。对Send to server部分使用BackgroudWorker