Использование OpenNETCF.Net.Ftp внутри класса, а не внутри формы Windows - PullRequest
0 голосов
/ 22 мая 2009

Пока что я использую объект FTP внутри формы Windows. FTP-объект работает в отдельном потоке, поэтому, чтобы мое приложение не зависало, я использую следующий фрагмент кода:

private void OnResponse(string response)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new StringDelegate(OnResponse), new object[] { response });
            return;
        }
    } //end of OnResponse

Мне не совсем ясно, что такое делегат строки, но это работает.

Однако я сейчас занимаюсь рефакторингом и хочу спрятать ftp в класс. Мой вопрос: как мне убедиться, что основной поток не зависает? Все ссылки в Интернете, касающиеся создания событий внутри классов, имеют смысл, но я не нашел ни одного примера, где приложение является многопоточным. Моя самая большая проблема была бы InvokeRequired.

В приведенном выше коде это форма. Если я прячу объект ftp внутри класса, такого как следующий:

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

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

«Это» становится объектом MyClass. Я не уверен, реализовано ли свойство InvokeRequired в классе (возможно, я должен заставить его реализовать специальный интерфейс, который имеет это свойство?). Или, может быть, я что-то упускаю и не должен использовать многопоточные объекты внутри классов?

Ответы [ 2 ]

1 голос
/ 23 мая 2009

Вам нужен элемент управления или что-то производное от элемента управления (не обязательно должно быть формой), созданное в потоке пользовательского интерфейса. Ваш MyClass, скорее всего, не должен обновлять пользовательский интерфейс напрямую, так что это не очень актуально - MyClass, вероятно, вызовет событие или вызовет обратный вызов.

Важное значение имеет пользовательский интерфейс, когда вы хотите что-то изменить в форме на основе события, поступающего из библиотеки FTP. Для этого вам нужен элемент управления или что-либо производное от элемента управления (опять же, это не обязательно должна быть форма), созданное в потоке пользовательского интерфейса. Используйте этот элемент управления для проверки InvokeRequired, и, если это правда, вызовите Invoke. В оригинале используется пользовательский делегат (вероятно, взят из примера FTP, так как он мне действительно знаком), но вы можете использовать любой делегат, какой захотите.

В Интернете существует множество примеров использования Control.Invoke, поэтому вы сможете реализовать его довольно легко.

0 голосов
/ 22 мая 2009

Наиболее вероятный способ создать это - позволить вызывающей стороне MyClass вызывать или не вызывать Invoke по мере необходимости. Я бы спроектировал ваш класс так, чтобы он вызывал событие, когда происходит ответ.

Помните, что только интерфейс, взаимодействующий с пользовательским интерфейсом Windows, должен быть Invoke-d в основном потоке. Любая другая обработка в OnResponse может быть выполнена в фоновом потоке без проблем.

Если ваш «MyClass» не является объектом Windows, таким как форма или элемент управления, то у вас нет InvokeRequired, как вы сказали. Но это НЕ НУЖНО InvokeRequired. Если какой-то другой класс, представляющий объект пользовательского интерфейса, должен что-то сделать в ответ на объект FTP, то этот объект пользовательского интерфейса может выполнить тест InvokeRequired.

Надеюсь, это понятно!


РЕДАКТИРОВАТЬ: addl info

Обработчик OnReceived определенно будет в вашем классе FTP. Поэтому я думаю о чем-то вроде этого:

публичный класс MyFTPClass { открытое событие EventHandler DataReceived; // форма пользовательского интерфейса может подписаться на это событие

 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); 

}

Это грубый набросок. Но основная идея заключается в том, что вы делаете то, что вы можете локально в фоновом потоке. Затем вы можете уведомить пользовательский интерфейс через событие.

...