Form Method on another thread not invoking the events - c#-3.0

I am trying to achieve an update form.
I use a library to open a form when there is an updated file and download using edtFTPNet
In the form I pass the FTP object and start download, in FormLoad i handle two events and i use Thread to StartDownload(). My two events never invoking, i use them to set a progress bar.
public partial class UpdateProgressForm : XtraForm
{
public FTPConnection FtpConn { get; set; }
public string UpdateFileName { get; set; }
public UpdateProgressForm()
{
InitializeComponent();
}
private void OnLoad(object sender, EventArgs e)
{
FtpConn.Downloading += FileDownLoading;
FtpConn.BytesTransferred += FileBytesTransfered;
}
private void FileDownLoading(object sender, FTPFileTransferEventArgs e)
{
progressBar.Properties.Maximum = (int) e.FileSize;
}
private void FileBytesTransfered(object sender, BytesTransferredEventArgs e)
{
progressBar.Position = (int) e.ByteCount;
}
public void StartDownload()
{
FtpConn.DownloadFile(#".\" + UpdateFileName, UpdateFileName);
}
private void OnShown(object sender, EventArgs e)
{
Thread tt = new Thread(StartDownload) {IsBackground = true};
tt.Start();
}
}
Library method calling the Form:
private void DownloadUpdateFile(string updateFileName)
{
using (ProgressForm = new UpdateProgressForm { FtpConn = FtpConn, UpdateFileName = updateFileName })
{
ProgressForm.ShowDialog();
}
}
Any help? Thank you.

Take a look in the designer and make sure you subscribe to those events
Make sure you Instanciate and Show the from from the Main Thread.

Are you sure that the event handlers are not invoked? I think your problem rather is that you try to update the progress bar on the worker thread on which the event handlers are invoke (which is not the thread on which the GUI was created). You should make sure that the GUI updates are performed on the correct thread:
private void FileDownLoading(object sender, FTPFileTransferEventArgs e)
{
progressBar.Invoke((MethodInvoker) delegate
{
progressBar.Properties.Maximum = (int) e.FileSize;
});
}

Related

Windows application freezes most of the time on button click

I am working on a windows application which freezes most of the time on button click events on Home Page. Please find the code below for your reference. Thanks
using System;
using System.Windows.Forms;
namespace FileMigrationAgen
{
public partial class HomePage : Form
{
public HomePage()
{
InitializeComponent();
}
private void tableLayoutPanel4_Paint(object sender, PaintEventArgs e)
{
}
private async void button1_Click(object sender, EventArgs e)
{
SharepointMigration sharepointMigration = new SharepointMigration();
sharepointMigration.Show();
this.Hide();
}
private async void button2_Click(object sender, EventArgs e)
{
OneDriveMigration oneDriveMigration = new OneDriveMigration();
oneDriveMigration.Show();
this.Hide();
}
private void HomePage_FormClosed(object sender, FormClosedEventArgs e)
{
Application.Exit();
}
}
}
I wouldn't recommend performing navigation in the manner that you have - hiding parent forms etc.
Have a look at this thread it has an example of using a static class to perform the navigation and keep track of the navigation stack.

how to pass class to another form?

im trying to passing a class which preserves the values in it across all forms. but i have no idea how to do it.
my default class:
namespace bankaccount
{
class Account
{
private string _name, _accountNo, _accountType;
private double _balance = 0;
public string Name
{
get{ return _name;}
set{ _name = value;}
}
public string AccountNo
{
get { return _accountNo; }
set { _accountNo = value; }
}
public string AccountType
{
get { return _accountType; }
set { _accountType = value; }
}
public double Balance
{
get { return _balance; }
set { _balance = value; }
}
public Account()
{
}
public Account(string name, string accountNo, string accountType, double balance)
{
_name = name;
_accountNo = accountNo;
_accountType = accountType;
_balance = balance;
}
public double withdraw(double withdraw)
{
return _balance = _balance - withdraw;
}
public double deposit(double deposit)
{
return _balance = _balance + deposit;
}
}
}
main menu form:
public partial class frmMainMenu : Form
{
public frmMainMenu()
{
InitializeComponent();
}
public void btnNewAccount_Click(object sender, EventArgs e)
{
this.Hide();
frmNewAccount NewAccount = new frmNewAccount();
NewAccount.Show();
}
public void btnDeposit_Click(object sender, EventArgs e)
{
this.Hide();
frmDeposit Deposit = new frmDeposit();
Deposit.Show();
}
public void btnWithdraw_Click(object sender, EventArgs e)
{
this.Hide();
frmWithdraw Withdraw = new frmWithdraw();
Withdraw.Show();
}
public void btnBalance_Click(object sender, EventArgs e)
{
this.Hide();
frmBalance Balance = new frmBalance();
Balance.Show();
}
}
New Account form (form to create object from the class)
public partial class frmNewAccount : Form
{
public frmNewAccount()
{
InitializeComponent();
}
private void btnRegister_Click(object sender, EventArgs e)
{
//Account newAccount = new Account();
string name = string.Copy(txtName.Text);
string accountNo = string.Copy(txtAccountNo.Text);
string accountType = string.Copy(txtAccountType.Text);
double amount = double.Parse(txtAmount.Text);
Account newAccount = new Account(name, accountNo, accountType, amount);
}
private Account btnMainMenu_Click(object sender, EventArgs e)
{
this.Hide();
frmMainMenu MainMenu = new frmMainMenu();
MainMenu.Show();
}
}
Deposit form
public partial class frmDeposit : Form
{
public frmDeposit()
{
InitializeComponent();
}
private void btnDeposit_Click(object sender, EventArgs e)
{
}
private void btnMainMenu_Click(object sender, EventArgs e)
{
this.Hide();
frmMainMenu MainMenu = new frmMainMenu();
MainMenu.Show();
}
}
what im trying to do here is create Account newAccount on New Account Form, using the data its created to be accessible in another form...
Your code has to be changed minimally to give this reference of an account to a child form. I would do it explicitly in constructor.
public partial class frmDeposit : Form
{
Account _account;
public frmDeposit(Account account)
{
_account = account;
InitializeComponent();
}
(...)
After this you can use inside the frmDeposit class the _account field.
This approach is typically better than using a property as you enforce the form to be initialized with an account.
And when you create your dialog to set deposit information, you will have to write instead of:
var depositForm = new frmDeposit(); //here you will get compilation error
depositForm.ShowDialog()
You will have to write:
var depositForm = new frmDeposit(account); //compilation error is fixed
depositForm.ShowDialog()
You usually don't pass classes, but instances (i.e. objects). Create an instance of the class in the form that starts your workflow. In every child form that's called, add a property
public BankAccount Account { get; set; }
and set the value of that property before showing the child form.
using (FrmChildForm frm = new FrmChildForm())
{
frm.Account = myBankAccount;
...
}
Another solution would be to create an instance variable in every child form as well and pass the account in the constructor:
using (FrmChildForm frm = new FrmChildForm(myBankAccount))
...
public class FrmChildForm : Form
{
private BankAccount _account;
public FrmChildForm(BankAccount theAccount)
{
_account = theAccount;
}
}
About your navigation
You're doing it wrong! You're filling up memory for nothing, creating instances over and over the place. Why?
Well, your main menu creates a child form, then hides itself. Your child form then generates a new main menu instead of just closing itself and showing the existing main form again! That's highly inefficient and prevents you from keeping the account instance I talked about above.
What you should do is this:
public void btnNewAccount_Click(object sender, EventArgs e)
{
frmNewAccount NewAccount = new frmNewAccount();
NewAccount.Account = myAccount;
NewAccount.FormClosing += SubFormClosing;
NewAccount.Show();
this.Hide();
}
Then, have a method SubFormClosing:
private void SubFormClosing(object sender, FormClosingEventArgs e)
{
this.Show();
}
Then, the code to return to the main form comes down to:
private void btnMainMenu_Click(object sender, EventArgs e)
{
this.Close();
}
This creates one main menu. Upon selecting an module, the module window is opened, the main menu is hidden. Instead of creating a new main menu when closing the module window, the old main menu is restored when the module window is closed.
The trick here is to attach an event handler to the closing event of the module form so the hidden menu form gets notified that it should show itself again.
And you should learn about modal dialogs. The "window" where a new account is created should actually be a modal dialog that collects the information. Then, the main menun sets its myAccount member variable based on the new account information. There's no need to pass the account to the "New Account" mask, as it creates a new account.

Guava EventBus: pause event posting

Is there any way to pause event posting by the EventBus from the guava library.
I have a method changeSomething() that posts an event (e.g. SomethingChangedEvent). Now this method is called in a loop by another method doStuff().
The problem is that the SomethingChangedEvent is posted on every call to changeSomething() even though only the last change matters. Due to the fact that the handlers of the event execute some heavy-weight calculations, the performance of the application degrades fast.
After the last time changeSomething() is executed I would like to tell guava to resume event processing.
Is there any way to tell guava to ignore all SomethingChangedEvents except the very last one?
I tried this pattern, derived from the poison pill pattern using sub-classing :
public class SomethingChangedEvent {
private final String name;
public SomethingChangedEvent(String name) {
this.name = name;
}
#Override
public String toString() {
return name;
}
}
public class IgnoreSomethingChangedEvent extends SomethingChangedEvent {
public IgnoreSomethingChangedEvent(String name) {
super(name);
}
}
public class HandleSomethingChangedEvent extends SomethingChangedEvent {
public HandleSomethingChangedEvent(String name) {
super(name);
}
}
private void eventBusTest() {
EventBus eventBus = new EventBus();
eventBus.register(new EventBusSomethingChanged());
eventBus.post(new SomethingChangedEvent("process this one"));
eventBus.post(new IgnoreSomethingChangedEvent("ignore"));
eventBus.post(new SomethingChangedEvent("don't process this one"));
eventBus.post(new HandleSomethingChangedEvent("handle"));
eventBus.post(new SomethingChangedEvent("process this one bis"));
}
public class EventBusSomethingChanged {
private boolean ignore;
#Subscribe
public void SomethingChanged(SomethingChangedEvent e) {
if (e instanceof IgnoreSomethingChangedEvent) {
ignore = true;
return;
}
if (e instanceof HandleSomethingChangedEvent) {
ignore = false;
return;
}
if (!ignore) {
System.out.println("processing:" + e);
}
}
}

How do you trigger an event across classes?

I am writing a Class Library that will be used by other applications. I am writing it in C#.NET. I am having a problem with triggering events across classes. Here is what I need to do...
public class ClassLibrary
{
public event EventHandler DeviceAttached;
public ClassLibrary()
{
// do some stuff
OtherClass.Start();
}
}
public class OtherClass : Form
{
public Start()
{
// do things here to initialize receiving messages
}
protected override void WndProc (ref message m)
{
if (....)
{
// THIS IS WHERE I WANT TO TRIGGER THE DEVICE ATTACHED EVENT IN ClassLibrary
// I can't seem to access the eventhandler here to trigger it.
// How do I do it?
}
base.WndProc(ref m);
}
}
Then in the application that is using the class library I will do this...
public class ClientApplication
{
void main()
{
ClassLibrary myCL = new ClassLibrary();
myCL.DeviceAttached += new EventHandler(myCl_deviceAttached);
}
void myCl_deviceAttached(object sender, EventArgs e)
{
//do stuff...
}
}
Probably the easiest option is to add a method to ClassLibrary which raises the event...i.e.
internal void RaiseDeviceAttached(object sender, EventArgs e)
{
if (DeviceAttached != null) DeviceAttached(sender, e);
}
Then, in OtherClass, simply call that method of ClassLibrary.
Another option is to go down the reflection route to trigger the event.

GWT Void remote services fail for seemingly no reason

I'm working on a GWT project and have several void remote services that seem to execute just fine, but on the client side, end up firing the onFailure() method. No exceptions are thrown anywhere, and the expected behavior is observed on the backend. I have no idea what could be going wrong. Here is the relevant code:
Interfaces and implementation...
#RemoteServiceRelativePath("DeleteSearchService")
public interface DeleteSearchService extends RemoteService {
/**
* Utility class for simplifying access to the instance of async service.
*/
public static class Util {
private static DeleteSearchServiceAsync instance;
public static DeleteSearchServiceAsync getInstance(){
if (instance == null) {
instance = GWT.create(DeleteSearchService.class);
}
return instance;
}
}
public void delete(SearchBean search);
}
public interface DeleteSearchServiceAsync {
public void delete(SearchBean bean, AsyncCallback<Void> callback);
}
public class DeleteSearchServiceImpl extends RemoteServiceServlet implements DeleteSearchService {
private static final long serialVersionUID = 1L;
#Override
public void delete(SearchBean search) {
try {
Connection conn = SQLAccess.getConnection();
String sql = "DELETE FROM `searches` WHERE `id`=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, search.getSearchId());
ps.execute();
sql = "DELETE FROM `searchsourcemap` WHERE `search-id` = ?";
ps = conn.prepareStatement(sql);
ps.setInt(1, search.getSearchId());
ps.execute();
return;
} catch (Exception e) {
// TODO Log error
e.printStackTrace();
}
}
}
Calling code...
private class DeleteListener implements ClickListener {
public void onClick(Widget sender) {
DeleteSearchServiceAsync dss = DeleteSearchService.Util.getInstance();
SearchBean bean = buildBeanFromGUI();
dss.delete(bean, new AsyncCallback<Void>(){
//#Override
public void onFailure(Throwable caught) {
// TODO log
SearchNotDeleted snd = new SearchNotDeleted();
snd.show();
}
//#Override
public void onSuccess(Void result) {
SearchDeleted sd = new SearchDeleted();
sd.show();
searchDef.getParent().removeFromParent();
}
});
}
}
I know I'm a jerk for posting like 500 lines of code but I've been staring at this since yesterday and can't figure out where I'm going wrong. Maybe a 2nd set of eyes would help...
Thanks,
brian
LGTM I'm afraid.
Are you using the hosted mode or a full-fledged browser? You can try switching and see if it helps.
Also, it might help listening to that //TODO and perform a GWT.log when onFailure is invoked.