简体   繁体   English

在类而不是Windows窗体中使用OpenNETCF.Net.Ftp

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

So far I am using an FTP object inside a Windows form. 到目前为止,我正在Windows窗体内使用FTP对象。 FTP object runs in a separate thread, so to ensure that my app doesn't freeze up, I use the following piece of code: FTP对象在单独的线程中运行,因此为了确保我的应用程序不会冻结,我使用以下代码:

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. 但是,我现在正在重构,希望将ftp隐藏到一个类中。 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. 我最大的担心是InvokeRequired。

In the code above this is a form. 在上面的代码中,这是一种形式。 If I hide the ftp object inside a class such as the following: 如果我将ftp对象隐藏在如下类中:

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

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

"This" becomes an object of MyClass. “这”成为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?). 我不确定是否在类上实现了InvokeRequired属性(也许我应该使其实现具有该属性的特殊接口?)。 Or perhaps I am missing something and I am not supposed to use multithreaded objects inside classes? 或者,也许我缺少某些东西,并且我不应该在类内部使用多线程对象?

You need a Control or something derived from Control (doesn't have to be a Form) that was created on the UI thread. 您需要一个Control或从UI线程上创建的,衍生自Control的东西(不必是Form)。 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. 您的MyClass可能不应该直接更新UI,因此在这里并不重要-MyClass可能会引发事件或调用回调。

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. 当您想根据来自FTP库的事件在Form上进行某些更改时,最重要的是UI。 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. 为此,您需要一个Control或从Control派生的任何东西(同样,也不必是一个Form),它是在UI线程上创建的。 Use that control to check InvokeRequired, and if it's true, call Invoke. 使用该控件检查InvokeRequired,如果为true,则调用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. 原始版本使用自定义委托(可能对我很熟悉,可能来自FTP示例),但是您可以使用所需的任何委托。

There are plenty of examples on the web for using Control.Invoke, so you should be able to get it implemented fairly easily. Web上有很多使用Control.Invoke的示例,因此您应该可以轻松实现它。

The most likely way to design this is to let the caller of 'MyClass' Invoke or not Invoke as needed. 设计此方法最可能的方法是让“ MyClass”的调用者根据需要调用或不调用。 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. 请记住,只有与Windows UI交互的代码需要被调用到主线程上。 Any other handling in OnResponse can be done in the background thread no problem. OnResponse中的任何其他处理都可以在后台线程中完成,没有问题。

If your 'MyClass' isn't a windows object like a form or control, then you don't have the InvokeRequired just like you said. 如果您的“ MyClass”不是窗体或控件之类的Windows对象,那么您就不会像您所说的那样具有InvokeRequired。 But it doesn't NEED InvokeRequired. 但这并不需要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. 如果其他代表UI对象的类确实需要对FTP对象做出响应,那么该UI对象可以执行InvokeRequired测试。

I hope that's clear! 我希望这很清楚!


EDIT: addl info 编辑:addl信息

The OnReceived handler would definitely be in your FTP class. OnReceived处理程序一定会在您的FTP类中。 So I'm thinking of something like this: 所以我在想这样的事情:

public class MyFTPClass { public event EventHandler DataReceived; 公共类MyFTPClass {公共事件EventHandler DataReceived; // the UI form can subscribe to this event // UI表单可以订阅此事件

 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. 然后,您可以通过事件通知UI。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM