Asked  7 Months ago    Answers:  5   Viewed   21 times

I know it has 3 methods. In my program I have a method to send a message. It is often late and the program sometimes doesn't send the message at all in response to a button press. At times it is as late as 5 seconds from what I would expect and the program freezes. I want to use a BackgroundWorker to send the message as expected and allow the program to run normally at all times. I had the code for sending the message in a button handler. Now where do I put this equivalent code? I would like all of this to still be handled by a button press.

Is this the appropriate handler?

backgroundWorker1.RunWorkerAsync();

and in:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {}

I'm going to put my code in the button handler? And this before:

carga.progressBar1.Minimum = 0;
carga.progressBar1.Maximum = 100;

Carga is my other form where the ProgressBar is. How do I use a BackgroundWorker in this scenario?

 Answers

51

You can update progress bar only from ProgressChanged or RunWorkerCompleted event handlers as these are synchronized with the UI thread.

The basic idea is. Thread.Sleep just simulates some work here. Replace it with your real routing call.

public Form1()
{
    InitializeComponent();

    backgroundWorker1.DoWork += backgroundWorker1_DoWork;
    backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;
    backgroundWorker1.WorkerReportsProgress = true;
}

private void button1_Click(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    for (int i = 0; i < 100; i++)
    {
        Thread.Sleep(1000);
        backgroundWorker1.ReportProgress(i);
    }
}

private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}
Tuesday, June 1, 2021
 
williamcarswell
answered 7 Months ago
78

Rightly or wrongly in an interface block you don't have access to the environment by host association. To fix this you need to import the datatype exlicitly:

[luser@cromer stackoverflow]$ cat type.f90
module m_serialization

  implicit none

  type :: t_savepoint
     integer :: savepoint_index
     real    :: savepoint_value
  end type t_savepoint

  interface

     subroutine fs_initializesavepoint(savepoint)
       Import :: t_savepoint
       type(t_savepoint) :: savepoint
     end subroutine fs_initializesavepoint


  end interface

end module m_serialization
[luser@cromer stackoverflow]$ gfortran -c type.f90

This is f2003.

However I suspect the way you have put this suggests you are not going about coding this up the best way. Better is simply to put the routine itself in the module. Then you don't need bother with the interface at all:

module m_serialization

  implicit none

  type :: t_savepoint
     integer :: savepoint_index
     real    :: savepoint_value
  end type t_savepoint

Contains

  Subroutine fs_initializesavepoint(savepoint)

    type(t_savepoint) :: savepoint 

    Write( *, * ) savepoint%savepoint_index, savepoint%savepoint_value

  End Subroutine fs_initializesavepoint

end module m_serialization
[luser@cromer stackoverflow]$ gfortran -c type.f90

Given that modules are really designed to deal with connected entities this is really the way to do it in Fortran. It also has the advantage of only requiring a f95 compiler, so is universally available (though admittedly import is commonly implemented)

Saturday, July 31, 2021
 
mariaoialvarez
answered 5 Months ago
63

If it has to be a real terminal and a real shell (and not just accepting a line of input, running some command, then displaying output) -- how about tmux?

You could use something like tee to get the output back into your program.

Note that tmux sessions may persist across your program runs, so you'd need to read up on how that works and how to control it.

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class embeddedTerminal(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self._processes = []
        self.resize(800, 600)
        self.terminal = QWidget(self)
        layout = QVBoxLayout(self)
        layout.addWidget(self.terminal)
        self._start_process(
            'xterm',
            ['-into', str(self.terminal.winId()),
             '-e', 'tmux', 'new', '-s', 'my_session']
        )
        button = QPushButton('List files')
        layout.addWidget(button)
        button.clicked.connect(self._list_files)

    def _start_process(self, prog, args):
        child = QProcess()
        self._processes.append(child)
        child.start(prog, args)

    def _list_files(self):
        self._start_process(
            'tmux', ['send-keys', '-t', 'my_session:0', 'ls', 'Enter'])

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = embeddedTerminal()
    main.show()
    sys.exit(app.exec_())

A bit more here: https://superuser.com/questions/492266/run-or-send-a-command-to-a-tmux-pane-in-a-running-tmux-session

Monday, August 2, 2021
 
Szenis
answered 5 Months ago
22

Subscribe to the RunWorkerCompleted event. That event contains the return value of the background operation.

Of course, that value would be returned from inside the DoWorkEventHandler, like so:

b.DoWork += new DoWorkEventHandler(
    delegate(object sender, DoWorkEventArgs e) {
        double returnValue = 0;
        for(int i=0;i<100;i++){
            returnValue += (i+1);
        }
        e.Result = returnValue;
    }
);
Friday, August 6, 2021
 
anjan
answered 4 Months ago
62

Thanks for the help, between those answers and one I found I've managed to get it work, the line I was missing is: BackgroundWorker worker = (BackgroundWorker)sender;

and then reference that worker object with worker.reportprogress(..)

The guide i found useful is: http://www.nerdparadise.com/tech/coding/csharp/backgroundworker/

perfect, thanks guys :)

Monday, August 30, 2021
 
Peter Thomas
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share