到目前为止,我使用的是Windows窗体内部的FTP对象。 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属性是在类实现(也许我应该让它实现具有这个属性的专用界面?)。 也许我失去了一些东西,我不应该用在类的多线程对象?
你需要从控制得到的控制什么的(不必是一个表格),这是在UI线程上创建的。 你可能MyClass的不应该直接更新UI,因此在这里没有真正相关 - MyClass的可能会引发一个事件或调用回调函数。
它真正重要的UI是,当你想改变基于从FTP库未来事件的窗体上的东西。 为此你需要从控制派生的控件或任何东西(同样,不一定是一个表格),这是在UI线程上创建的。 使用该控件来检查InvokeRequired,如果这是真的,叫调用。 原来采用的是自定义委托(很可能来自FTP样品,因为它看起来非常熟悉我),但你可以使用任何你想要的代表。
有大量的网络使用Control.Invoke的例子,所以你应该能够得到它的实现很容易。
设计这个最有可能的方式是让的“MyClass的”调用来电或根据需要调用没有。 我会设计类的响应时发生触发事件。
请记住,它是与需要被调用-D在主线程中的窗口UI交互的唯一代码。 在OnResponse任何其他操作可以在后台完成线程没有问题。
如果你的“MyClass的”不是Windows对象如窗体或控件,那么你就没有InvokeRequired就像你说的。 但它并不需要InvokeRequired。 如果代表UI目标的一些其他类确实需要做一些响应FTP对象,以及该UI对象可以做InvokeRequired测试。
我希望这是明确的!
编辑:ADDL信息
该OnReceived处理器肯定是在你的FTP类。 所以我想的是这样的:
公共类MyFTPClass {公共事件EventHandler的DataReceived; //该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);
}
这是一个大致的轮廓。 但基本的想法是,你在后台线程做什么,你可以在本地。 然后你就可以通过将事件通知的UI。