首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在线程中使用“此”!

如何在线程中使用“此”!
EN

Stack Overflow用户
提问于 2011-04-05 09:10:28
回答 3查看 1.8K关注 0票数 0

我试图使用一个单独的线程调用我的静态函数,我的函数中有类似于this->listBox1->Items->Add(s);的东西。编译器显示,我不能在静态函数中使用this。我试图使函数非静态(即删除static关键字),但当我这样做时,编译器再次显示两个错误:

Error 2 C3350:'System::Threading::ThreadStart‘:委托构造函数需要2个参数(S)c:\user\ahmed\documents\visual studio 2010\projects\testscan\testscan\Form1.h116

错误1错误C2276:'&‘:绑定成员函数表达式c:\user\ahmed\documents\visual studio 2010\projects\test扫描\test扫描\Form1.h116

编辑

职能:

代码语言:javascript
复制
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);
}

怎么称呼它:

代码语言:javascript
复制
void button1_Click(System::Object^  sender, System::EventArgs^  e) {
    Thread ^thr1 = gcnew Thread(gcnew ParameterizedThreadStart(this,&Form1::ScanMyDir));
    thr1->Start("c:\\"); 
}

对形式载荷的修改:

代码语言:javascript
复制
void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
    System::Windows::Forms::Control::CheckForIllegalCrossThreadCalls = false;
}

新错误:(:

Error 5 C3352:‘visual::form1:ScanMyDir(System::String ^)’:指定的函数不匹配委托类型'void (System:Object ^)‘c:\user\ahmed\documents\visual studio 2010\testscan\testscanForm1.117

错误1错误C2273:“函数式强制转换”:“->”操作符c:\user\ahmed\documents\visual studio 2010\projects\testscan\testscan\Form1.h105的右侧非法

错误2错误C2227:‘->listBox1 1’的左边必须指向class/struct/union/泛型类型c:\user\ahmed\documents\visual studio 2010\projects\testscan\testscan\Form1.h105

错误3错误C2227:左侧的‘->项’必须指向类/struct/union/泛型类型c:\user\ahmed\documents\visual studio 2010\projects\testscan\testscan\Form1.h105

错误4错误C2227:左侧必须指向class/struct/union/泛型类型c:\\ahmed\documents\visual studio 2010\projects\testscan\testscan\Form1.h105

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-05 12:40:47

不需要使您的功能静态。给定错误是由于您使用的语法错误造成的。假设您的表单类型为FormType,

代码语言:javascript
复制
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(),然后在函数中重新构造它。

代码语言:javascript
复制
static void ScanMydir(Object ^ param)
{
  FormType ^ ft = static_cast<FormType^>(param); 
  //..
  ft->listBox1->Items->Add(fileName);
  //..
}

在这种情况下,您必须使用ParametrizedThreadStart()

代码语言:javascript
复制
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”,然后在窗体上加载函数写

代码语言:javascript
复制
void FormType_Load(Object ^sender, EventArgs ^ e)
{
  System::Windows::Forms::Control::CheckForIllegalCrossThreadCalls = false;
  //....
}

但是这可能是危险的,取决于您的实现,您必须保证listbox1->items的线程安全。

还可以听听“”这个家伙说的话。他说的是好事。

票数 3
EN

Stack Overflow用户

发布于 2011-04-05 09:25:07

好的,基本原则:

  1. Static意味着该方法是,而不是对象的成员。它是类类型的成员,与该类的所有对象都是相同的。所以,没有这个associated.
  2. Read,因为没有对象编译器错误。阅读函数定义以传递正确的parameters...
  3. When --您可以这样做,您可能会出错,因为您试图使用来自不同线程的GUI函数。这将导致运行时错误(有时)。

检查这个:UI Thread .Invoke() causing handle leak?

票数 2
EN

Stack Overflow用户

发布于 2011-04-05 09:24:51

免责声明:我没有使用托管C++,只使用C#和香草C++。因此,这个答案可能是不正确的。

ThreadStart委托可以接受一个参数。将类的实例传递给它,并在静态线程方法中将其转换为类。这不是this,而是几乎相同的事情。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5549611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档