Using OpenNETCF.Net.Ftp inside a class instead of inside a Windows Form

拥有回忆 提交于 2019-12-14 04:03:53

问题


So far I am using an FTP object inside a Windows form. FTP object runs in a separate thread, so to ensure that my app doesn't freeze up, 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 am not completely clear on what a string delegate is, but this works.

However, I am now refactoring and wish to hide the ftp into a class. My question is how do I make sure the main thread doesn't freeze? All the references online regarding raising events inside classes make sense, but I haven't found a single example where the application is multithreaded. My biggest concern would be InvokeRequired.

In the code above this is a form. If I hide the ftp object inside a class such as the following:

abstract class MyClass
{
    //data members
    private FTP _ftp;

    //other data members, methods, and properties etc
}

"This" becomes an object of MyClass. I am not sure if InvokeRequired property is implemented on class (perhaps I should make it implement a special interface that has that property?). Or perhaps I am missing something and I am not supposed to use multithreaded objects inside classes?


回答1:


You need a Control or something derived from Control (doesn't have to be a Form) that was created on the UI thread. Your MyClass likely shouldn't be updating the UI directly, so it's not really relevant here - MyClass would probably raise an event or invoke a callback.

Where it gets important is up at the UI when you want to change something on a Form based on an event coming from the FTP library. For that you need a Control or anything derived from Control (again, doesn't have to be a Form) that was created on the UI thread. Use that control to check InvokeRequired, and if it's true, call Invoke. The original uses a custom delegate (probably comes from the FTP sample, as it looks really familiar to me), but you could use any delegate you want.

There are plenty of examples on the web for using Control.Invoke, so you should be able to get it implemented fairly easily.




回答2:


The most likely way to design this is to let the caller of 'MyClass' Invoke or not Invoke as needed. I would design your class to fire an event when the Response happens.

Remember that it's only code that interacts with the windows UI that needs to be Invoke-d onto the main thread. Any other handling in OnResponse can be done in the background thread no problem.

If your 'MyClass' isn't a windows object like a form or control, then you don't have the InvokeRequired just like you said. But it doesn't NEED InvokeRequired. If some other class representing a UI object does need to do something in response to the FTP object, well that UI object can do the InvokeRequired test.

I hope that's clear!


EDIT: addl info

The OnReceived handler would definitely be in your FTP class. So I'm thinking of something like this:

public class MyFTPClass { public event EventHandler DataReceived; // the 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 in the background thread. Then you can notify the UI through an event.



来源:https://stackoverflow.com/questions/899328/using-opennetcf-net-ftp-inside-a-class-instead-of-inside-a-windows-form

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!