Using OpenNETCF.Net.Ftp inside a class instead of a Windows internal form
So far I am using FTP object inside Windows Form. The FTP object runs on a separate thread, so to make sure my application doesn't freeze, I use the following piece of code:
private void OnResponse(string response)
{
if (this.InvokeRequired)
{
this.Invoke(new StringDelegate(OnResponse), new object[] { response });
return;
}
} //end of OnResponse
I don't quite understand what a string delegate is, but it works.
However, now I am refactoring and want to hide ftp in the class. My question is, how can I make sure the main thread does not freeze? All the links on the internet regarding raising events within classes make sense, but I haven't found a single example where the application is multithreaded. My biggest concern is InvokeRequired.
In the above code, this is a form. If I hide the ftp object inside a class like:
abstract class MyClass
{
//data members
private FTP _ftp;
//other data members, methods, and properties etc
}
"This" becomes a MyClass object. I'm not sure if the InvokeRequired property is implemented in the class (perhaps I should force it to implement a custom interface that has this property?). Or perhaps I'm missing something and I shouldn't be using multithreaded objects inside classes?
a source to share
You want a control or something derived from a control (not necessarily a form) created on the UI thread. Your MyClass probably shouldn't be updating the UI directly, so it doesn't really matter here - MyClass will probably raise an event or call a callback.
Where it becomes important depends on the UI when you want to change something on the form based on an event coming from the FTP library. To do this, you need a Control or anything derived from a Control (again, it doesn't have to be a Form) that was created on the UI thread. Use this control to check InvokeRequired, and if true, call Invoke. The original uses a custom delegate (it probably comes from the FTP example as it looks very familiar to me), but you can use any delegate you want.
There are many examples of using Control.Invoke on the internet, so you can easily implement it.
a source to share
The most likely way to create it is to let the caller of MyClass call or not call as needed. I would design your class to fire an event when a response occurs.
Remember, this is only code that interacts with the Windows UI, which should be Invoke-d on the main thread. Any other processing in OnResponse can be done on a background thread without issue.
If your "MyClass" is not a Windows object such as a form or control, then you don't have InvokeRequired as you said. But this DOES NOT NEED InvokeRequired. If any other class that represents the UI object needs to do something in response to the FTP object, it's good that the UI object can perform the InvokeRequired test.
I hope this is clear!
EDIT: additional information
The OnReceived handler will definitely be in your FTP class. So I am thinking of something like this:
public class MyFTPClass {public event EventHandler DataReceived; // UI form can subscribe to this event
private void OnReceived()
{
//so the FTP has returned data
// Do stuff here that can be on the background thread like saving
// the file in an appropriate place, or whatever.
// now trigger the DataReceived event. Anyone who cares about data being received
// can subscribe to this and do whatever is appropriate.
if (DataReceived) DataReceived(this, EventArgs.Empty);
}
This is a rough outline. But the basic idea is that you do what you can locally on a background thread. Then you can notify the UI via an event.
a source to share