Cannot get past thread.join in c#

Advertisements

I’ve tried implementing some code to launch a thread an perform an operation after it joins. The only problem is that it never returns from the thread. Can anyone tell me what I’m doing wrong?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Prototype
{
    public partial class Form1 : Form
    {

        public static string Decrypt(string cipherData, string keyString)
        {
            // decrypt stuff
        }

        public List<String[]> loadDB()
        {
            // load db
        }

        public List<String[]> StartForm()
        {
            List<String[]> data = loadDB();
            Application.Run(new Splash());
            return data;
        }

        public Form1()
        {
            List<String[]> data = null;
            Thread t = new Thread(() => { data = StartForm(); });
            t.Start();
            Thread.Sleep(5000);
            Debug.WriteLine("There");
            Debug.WriteLine(t.ThreadState.ToString());
            t.Join();
            Debug.WriteLine("Here" + data[0][0]);
            InitializeComponent();
            label1.Text = data[0][0];
        }
    }
}

I was expecting "Here" + datum to output.

>Solution :

The issue is that the StartForm method is starting an application thread by calling Application.Run(new Splash());, and the UI thread is blocked by the t.Join() method call, which is waiting for the application thread to complete.

To fix this issue, you can move the Application.Run method call to a separate method, like this:

public void ShowSplash()
{
    Application.Run(new Splash());
}

Then, in the constructor of Form1, you can start a new thread for the ShowSplash method, wait for it to complete, and then start another thread for the StartForm method, like this:

public Form1()
{
    List<String[]> data = null;

    Thread splashThread = new Thread(ShowSplash);
    splashThread.Start();

    splashThread.Join(); // wait for the splash thread to complete

    Thread formThread = new Thread(() => { data = StartForm(); });
    formThread.Start();

    formThread.Join(); // wait for the form thread to complete

    Debug.WriteLine("Here" + data[0][0]);
    InitializeComponent();
    label1.Text = data[0][0];
}

This should allow the Form1 constructor to wait for the application thread to complete, and then display the data from the StartForm method.

Leave a ReplyCancel reply