我试图使用一个单独的线程调用我的静态函数,我的函数中有this->listBox1->Items->Add(s);
。编译器显示我不能在静态函数中使用this
。我试图使我的函数非静态(即删除static
关键字)但是当我这样做时,编译器再次显示两个错误:
错误2错误C3350:'System :: Threading :: ThreadStart':委托构造函数需要2个参数c:\ users \ ahmed \ documents \ visual studio 2010 \ projects \ testscan \ testscan \ Form1.h 116
错误1错误C2276:'&' :绑定成员函数表达式非法操作c:\ users \ ahmed \ documents \ visual studio 2010 \ projects \ testscan \ testscan \ Form1.h 116
修改:
功能:
void ScanMyDir(String^ SourceDir)
{
array <String^> ^fileEntries = Directory::GetFiles(SourceDir);
for each (String^ fileName in fileEntries)
this->Form1->listBox1->Items->Add(fileName);
array<String^> ^SubDirEntries = Directory::GetDirectories(SourceDir);
for each (String^ subdir in SubDirEntries)
if ((File::GetAttributes(subdir) & FileAttributes::ReparsePoint)!= FileAttributes::ReparsePoint)
ScanMyDir(subdir);
}
打电话的方式:
void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Thread ^thr1 = gcnew Thread(gcnew ParameterizedThreadStart(this,&Form1::ScanMyDir));
thr1->Start("c:\\");
}
表单加载修改:
void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
System::Windows::Forms::Control::CheckForIllegalCrossThreadCalls = false;
}
新错误:(:
错误5错误C3352:'void testScan :: Form1 :: ScanMyDir(System :: String ^)':指定的函数与委托类型'void(System :: Object ^)'c:\ users \不匹配ahmed \ documents \ visual studio 2010 \ projects \ testscan \ testscan \ Form1.h 117
错误1错误C2273:'function-style cast':非法作为' - &gt;'的右侧运算符c:\ users \ ahmed \ documents \ visual studio 2010 \ projects \ testscan \ testscan \ Form1.h 105
错误2错误C2227:' - &gt; listBox1'的左侧必须指向类/ struct / union / generic类型c:\ users \ ahmed \ documents \ visual studio 2010 \ projects \ testscan \ testscan \ Form1.h 105
错误3错误C2227:' - &gt;项'左侧必须指向类/ struct / union / generic类型c:\ users \ ahmed \ documents \ visual studio 2010 \ projects \ testscan \ testscan \ Form1.h 105
错误4错误C2227:左边的' - &gt;添加'必须指向类/ struct / union / generic类型c:\ users \ ahmed \ documents \ visual studio 2010 \ projects \ testscan \ testscan \ Form1.h 105
答案 0 :(得分:3)
无需使您的功能保持静态。给定错误是由于您使用的语法错误。 假设您的表单类型为FormType,
void ScanMyDir()
{
//....
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
Thread ^thr1 =gcnew Thread(gcnew ThreadStart(this,&FormType::ScanMyDir));
thr1->Start();
}
如果你坚持让它静止,就像@jgauffin说的那样将表单作为Object
参数传递给ScanMyDir()
,然后将其重新形成为函数中的形式。
static void ScanMydir(Object ^ param)
{
FormType ^ ft = static_cast<FormType^>(param);
//..
ft->listBox1->Items->Add(fileName);
//..
}
在这种情况下,您必须使用ParametrizedThreadStart()
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
Thread ^thr1 =gcnew Thread(gcnew ParametrizedThreadStart(&FormType::ScanMyDir));
// it is static no need for "this"
thr1->Start(this);
}
但至少将ScanMyDir()
函数设为私有并阻止外部访问。
现在可能你会有另一个错误,说“你不能用不同的线程触摸GUI”,然后在你的表单加载函数上写
void FormType_Load(Object ^sender, EventArgs ^ e)
{
System::Windows::Forms::Control::CheckForIllegalCrossThreadCalls = false;
//....
}
但这可能很危险,具体取决于您的实施,您必须保证listbox1->items
的线程安全。
还听听@Yochai Timmer小伙子说的话。他说的很好。
答案 1 :(得分:2)
好的,基本原则:
静态表示该方法 NOT 是该对象的成员。它是Class类型的成员,并且与该类的所有对象相同。所以,没有这个,因为没有关联的对象。
读取编译器错误。阅读函数定义以传递正确的参数......
当你使用它时,你可能会遇到错误,因为你试图从另一个线程使用GUI函数。这将导致运行时错误(有时)。
答案 2 :(得分:1)
免责声明:我没有使用过托管C ++,只有C#和vanilla C ++。因此,这个答案可能不正确。
ThreadStart
委托可以参数。将类的实例传递给它并将其转换为静态线程方法中的类。它不是this
,而是几乎相同的东西。