Calum Murray
Calum Murray

Reputation: 1192

Multiple Forms in separate threads

I'm trying to run an ATM Simulation in C# with Windows Forms that can have more than one instance of an ATM machine transacting with a bank account simultaneously.

The idea is to use semaphores/locking to block critical code that may lead to race conditions.

My question is this:

How can I run two Forms simultaneously on separate threads? In particular, how does all of this fit in with the Application.Run() that's already there?

Here's my main class:

public class Bank
{
    private Account[] ac = new Account[3];
    private ATM atm;


    public Bank()
    {
        ac[0] = new Account(300, 1111, 111111);
        ac[1] = new Account(750, 2222, 222222);
        ac[2] = new Account(3000, 3333, 333333);


        Application.Run(new ATM(ac));


    }

    static void Main(string[] args)
    {
        new Bank();
    }
}
...that I want to run two of these forms on separate threads...

public partial class ATM : Form
{
    //local reference to the array of accounts
    private Account[] ac;

    //this is a reference to the account that is being used
    private Account activeAccount = null;

    private static int stepCount = 0;

    private string buffer = "";

    // the ATM constructor takes an array of account objects as a reference
    public ATM(Account[] ac)
    {
        InitializeComponent();  //Sets up Form ATM GUI in ATM.Designer.cs
        this.ac = ac;
    }
...

I've tried using

Thread ATM2 = new Thread(new ThreadStart(/*What goes in here?*/));

But what method do I put in the ThreadStart constructor, since the ATM form is event-driven and there's no one method controlling it?

EDIT:

I've tried replacing Application.Run(new ATM(ac)); with

ATM atm1 = new ATM(ac);
ATM atm2 = new ATM(ac);
Thread ATM2_T = new Thread(new ThreadStart(atm1.Show));
Thread ATM1_T = new Thread(new ThreadStart(atm2.Show));
ATM1_T.Start();
ATM2_T.Start();

in the Bank constructor. Nothing is displayed and the program drops-off the end of the Main() function.

Upvotes: 3

Views: 13796

Answers (3)

TsunamiCoder
TsunamiCoder

Reputation: 120

The above is unsafe code

Please find the threadsafe code:

Thread ATM2 = new Thread(new ThreadStart(ThreadProc));
ATM2.Start();

It calls this method:

private void ThreadProc()
{
    if(InvokeRequired)
    {
        this.Invoke(new Action(() => CreateAndShowForm()));
        return;
    }
    CreateAndShowForm();

}

private void CreateAndShowForm()
{
    var frm = new ATM();
    frm.ShowDialog();
}

Upvotes: 1

Brad Rem
Brad Rem

Reputation: 6026

Here's what I think you need to do:

Thread ATM2 = new Thread(new ThreadStart(ThreadProc));
ATM2.Start();

It calls this method:

private void ThreadProc()
{
    var frm = new ATM();
    frm.ShowDialog();
}

Upvotes: 9

hehewaffles
hehewaffles

Reputation: 582

In Bank.Main(), try relpacing Application.Run(new ATM(acc)) with new ATM(acc).Show(). You can use the Form.Show() method as many times as you want. If I recall correctly, the application will close when all forms are closed (although I could be mistaken--try this with the VS debugger)

Upvotes: 0

Related Questions