关于线程传string值的问题

baody8 2018-11-30 02:08:21
主线程定义,一个SK字符串变量,和一个LISTBOX


子线程进行赋值


运行结果是ListBox得到了值,但是SK变量木有[color=#FF0000][/color]

...全文
306 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_43940926 2018-12-04
  • 打赏
  • 举报
回复
对于技术上的事想请教您些问题,可以沟通一下吗
whb00120012 2018-12-04
  • 打赏
  • 举报
回复
constructor TTest.Create(ASk: PString; AL:^TListbox);
改为指针即可。
whb00120012 2018-12-04
  • 打赏
  • 举报
回复
constructor TTest.Create(ASk: PString; AL:^TListbox);

把参数改为指针即可。
  • 打赏
  • 举报
回复
首先你要明白, Delphi的VCL架构 UI刷新是主进程控制的, 所以你在线程里操作包含UI的控件很容易引起资源访问冲突, 如果使用sync方式和不使用线程区别不大 所以你应该吧所有数据计算处理的部分放到线程里, 处理完毕后通过同步或者消息方式吧结果数据交给主进程, 由主进程完成对UI的刷新
baody8 2018-12-03
  • 打赏
  • 举报
回复
引用 6 楼 堕落恶魔_Delphi 的回复:
你的sk是form1里的, 传递给线程的fa时, 属于引用传递(但是fa并不是sk的引用, 只是值引用, 这时delphi对string类型的特殊处理), 但是在线程的execute时你对fa赋值了, 这时fa会重新申请一块内存来存放新值, 而sk的原值并不会出现变化

如果你希望在线程里修改fa的值同时sk的值也跟着变化, 那么你需要明确吧fa定义成sk的引用, 也就是指针PString

另外, 强烈不建议在线程里使用VLC可视控件, 因为不是线程安全


type
Ttest=class(TThread)
private
{ Private declarations }
Fa: PString;
protected
procedure Execute; override;
public
{ Public declarations }
constructor Create(ASk: PString; AL:TListbox);
end;

constructor TTest.Create(ASk: PString; AL:TListbox);
begin
FreeOnTerminate := False;
inherited Create(False);
FA:=ASK; // 值的传递 此处仅带入一个字符串值
end;

procedure TTest.Execute;
begin
FA^:='测试';
end;

//-------------------------------------------------------------------

procedure TForm1.Button2Click(Sender: TObject);
begin
sk := '123';
with Ttest.Create(@sk, nil) do
begin
WaitFor;
Free;
end;
Caption := sk;
end;



问题是.....有些东西必须要线程显示数据.
  • 打赏
  • 举报
回复
你的sk是form1里的, 传递给线程的fa时, 属于引用传递(但是fa并不是sk的引用, 只是值引用, 这时delphi对string类型的特殊处理), 但是在线程的execute时你对fa赋值了, 这时fa会重新申请一块内存来存放新值, 而sk的原值并不会出现变化 如果你希望在线程里修改fa的值同时sk的值也跟着变化, 那么你需要明确吧fa定义成sk的引用, 也就是指针PString 另外, 强烈不建议在线程里使用VLC可视控件, 因为不是线程安全

type
  Ttest=class(TThread)
  private
    { Private declarations }
    Fa: PString;
  protected
    procedure Execute; override;
  public
    { Public declarations }
    constructor Create(ASk: PString; AL:TListbox);
  end;

constructor TTest.Create(ASk: PString; AL:TListbox);
begin
  FreeOnTerminate := False;
  inherited Create(False);
  FA:=ASK;          // 值的传递      此处仅带入一个字符串值
end;

procedure TTest.Execute;
begin
  FA^:='测试';
end;

//-------------------------------------------------------------------

procedure TForm1.Button2Click(Sender: TObject);
begin
  sk := '123';
  with Ttest.Create(@sk, nil) do
  begin
    WaitFor;
    Free;
  end;
  Caption := sk;
end;

lyhoo163 2018-12-01
  • 打赏
  • 举报
回复
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
Ttest=class(TThread)
private
{ Private declarations }
Fa:String;
FL:TListbox;
FS:TMemo;
protected
procedure Execute; override;
public
{ Public declarations }
constructor Create(ASk:string;AL:TListbox);
end;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ListBox1: TListBox;
Edit1: TEdit;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
work:TTest;
SK:string;
public
{ Public declarations }
end;

var
Form1: TForm1;
s:string;

implementation

{$R *.dfm}

constructor TTest.Create(ASk:string;AL:TListbox);
begin
inherited Create(False);
FA:=ASK; // 值的传递 此处仅带入一个字符串值
Fl:=Al; // 完成地址传递 对Fl的操作,就是对AL的 操作即对Listbox1的操作
ShowMessage(FA);
end;

procedure TTest.Execute;
begin
FA:='测试';
Fl.items.add(FA);
S:=FA;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
SK:='AAA';
work:=TTest.Create(SK,ListBox1);
Edit1.Text:=S;
end;

end.

代码中,关键的二句,功能 是不一样的:
FA:=ASK; 它是值的传递,此处仅向线程中,带入一个字符串值
Fl:=Al; 完成地址传递,这样,在线程中对Fl的操作,就是对AL的 操作,即对Listbox1的操作,所以它能Listbox1赋值。

你对这二句的功能没有正确识别,造成使用上的错误(功能不一样)。因此,在你线程中,就没有对SK的操作,即使你能ASK操作,它也是带不出字符串值的。
线程中可以对,全局Sting类型,进行赋值。你可以在,程序中定义S为全局变量,线程中就可以对直接S进行操作了。
BlueStorm 2018-12-01
  • 打赏
  • 举报
回复
去掉Fa变量,直接使用ASK变量 或者,在execute过程返回前赋值一下:ASK:= Fa
baody8 2018-11-30
  • 打赏
  • 举报
回复
引用 1 楼 BlueStorm 的回复:
构造函数应该改为:constructor Create(var ASK: String; AL: TListBox);


不行试过
baody8 2018-11-30
  • 打赏
  • 举报
回复
引用 楼主 baody8 的回复:
主线程定义,一个SK字符串变量,和一个LISTBOX


子线程进行赋值


运行结果是ListBox得到了值,但是SK变量木有[color=#FF0000][/color]


传址不行,试过的
BlueStorm 2018-11-30
  • 打赏
  • 举报
回复
构造函数应该改为:constructor Create(var ASK: String; AL: TListBox);

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧