0

So I am trying to executing javascript in my forms program, which is in visual studio. I am using C#. I have created a virtual web browser, and I am running the code in it which works fine. The only problem is I need to run a wait function in the script, but that freezes the whole program. I am trying to make a new thread and run the javascript in that so I can wait without freezing the uis. I have been trying to do this but the thread exits before the javascript code runs more than a single line because it thinks there is no code left to execute. This is because the javascript code is in the web browser HTML page. The thread stopping makes the javascript execution stop. The javascript code works fine if I run it in the main script since the thread stays open, but I can't run wait without freezing the program. I have tried running a timer to keep it open but it doesn't work. Is there any way I can force a thread to not auto-close?

Thread code to start the web browser:

public void ThreadStart3()
{
    LogToConsole("Starting Script!", true);
    WebBrowser Browser = new WebBrowser();
    Browser.ScriptErrorsSuppressed = false;
    var ns = new ScriptManager(_Form, _Num, _ConsoleRun, _MiniConsoleRun, @"G:\MemuProject\MemuScripter\Scripts\" + _Name + @"\", Int32.Parse(_Table[_LowestID][7]), _Device, _Table[_LowestID][1]);
    Browser.ObjectForScripting = ns;
    Browser.Navigate(@"G:\MemuProject\MemuScripter\Scripts\" + _Name + @"\" + _Name + @".html");
    var timer1 = new System.Windows.Forms.Timer();
    timer1.Tick += new EventHandler(TimerRun);
    timer1.Interval = 20000; // in miliseconds
    timer1.Start();

     // EVEN WITH A TIMER THE THREAD STILL CLOSES!
}

Code to create the new thread:

var t = new Thread(ThreadStart3);
t.SetApartmentState(ApartmentState.STA);
t.IsBackground = true;
t.Start();
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Lucas S
  • 1
  • 1
  • Not the only problem, the timer can't tick and the browser cannot raise any events. An STA apartment must run a dispatcher loop, Application.Run(). Which then automagically also prevents the thread from terminating. [Look here](https://stackoverflow.com/questions/4269800/webbrowser-control-in-a-new-thread). – Hans Passant Jan 01 '20 at 12:05

3 Answers3

0

Instead of spawning a thread manually you would better use TPL. Mark your ThreadStart3 as async method. Then simply await this method and continue when it's done executing. You cannot stop a thread from closing. It's how the thread works.

public async Task ThreadStart3()

await ThreadStart3()

the nature of TPL threads is background by default and you don't need to handle if a new thread is required at all or not.

Siavash Rostami
  • 1,883
  • 4
  • 17
  • 31
  • Can I get an example of how you would use this? Like a simple script calling on the task I'm just a bit confused on how to do it. – Lucas S Jan 01 '20 at 06:59
  • Also, I don't know if this will work because the place that would call on await threadstart3 is in an event which was called on by a function in a class which was called by a function in another class. I don't know if it would work to mark all of them async, but your the expert. – Lucas S Jan 01 '20 at 07:14
  • You'd better start with reading this. at least the first few essential topics, as explaining here doesn't work. https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl – Siavash Rostami Jan 01 '20 at 08:29
0

Do you need ThreadStart3 method to be run for a long time ? You can use the System.Threading.CancellationTokenSource to get the System.Threading.CancellationToken and get the signal to terminate the ThreadStart3 method

Like below:

public void ThreadStart3(CancellationToken cancelToken)
{
  // do you work with browser and script
  // then wait for signal to terminate
  while (!cancelToken.IsCancellationRequested)
    Thread.Sleep(200);
}

it can be used like

var source = new CancellationTokenSource();
Task.Run(() => ThreadStart3(source.Token));
// ThreadStart3 is working until source.Cancel() method is called

// you have to call source.Cancel() when ThreadStart3 is not needed any more (on program exit)
oleksa
  • 3,688
  • 1
  • 29
  • 54
  • Is there any way to make the task run on a single thread instead of a multi-thread? For some reason, vs doesn't let you make web browsers in multithreaded functions. Link to screen shot of error: https://drive.google.com/file/d/1bAfKJOdLUBYPe6iM60FANXbTuadhCa2E/view?usp=sharing – Lucas S Jan 01 '20 at 20:52
  • @LucasS well, you can put browser control on the form (just make it 10x10 pixels and hide it under the panel or any other control) and do not use a threading any more. – oleksa Jan 02 '20 at 09:38
0

You can close this because I found a solution, but im not going to post it here as overflow people seem to be very unhelpful.

Lucas S
  • 1
  • 1