我创建一个辅助线程 从全局数组MyArray中循环随机抽取一个(根据数组长度产生的产生随机下标),并显示在文本框中。当主线程按下回车键后,辅助线程suspend,把抽取的数从全局数组删除,数组长度-1 .
再按下回车键,resume 辅助线程。可是在有些机器上运行会死机。或者有时会死机。
是不是由于主线程修改了全局数组引起的? 怎么解决?谢谢!!!

解决方案 »

  1.   

    其实是个抽奖程序
    //form
    object Form1: TForm1
      Left = 188
      Top = 168
      Width = 544
      Height = 375
      Caption = 'Form1'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      KeyPreview = True
      OldCreateOrder = False
      OnCreate = FormCreate
      OnKeyDown = FormKeyDown
      PixelsPerInch = 96
      TextHeight = 13
      object Label1: TLabel
        Left = 32
        Top = 32
        Width = 48
        Height = 13
        Caption = '当前号码'
      end
      object Label2: TLabel
        Left = 248
        Top = 24
        Width = 72
        Height = 13
        Caption = '所有选中号码'
      end
      object lbtotal: TLabel
        Left = 40
        Top = 80
        Width = 28
        Height = 13
        Caption = 'lbtotal'
      end
      object Edit1: TEdit
        Left = 96
        Top = 24
        Width = 121
        Height = 21
        TabStop = False
        ImeName = '中文 (简体) - 微软拼音'
        ReadOnly = True
        TabOrder = 0
      end
      object Memo1: TMemo
        Left = 328
        Top = 16
        Width = 113
        Height = 321
        ImeName = '中文 (简体) - 微软拼音'
        ReadOnly = True
        TabOrder = 1
      end
    end
    //***********************代码**********************unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TDrawThread = class(TThread)
      private
        //显示随机抽出的数
        procedure ShowDigtal;
      protected
        procedure Execute; override;
        //抽奖
        procedure DrawPrize;
      public
        //当前的随机位置
        FRandomFoot:Integer;
        //要抽出的总数
       FNeedDrawCount:Integer;
        //已经抽出的数目
        FHasDrawCount:Integer;
        //按下回车键 判定号码停止滚动还是开始滚动
        FStop:Boolean;
        //删除全局数组刚选中的数
        procedure DelOne;
        constructor Create(NeedDrawCount:Integer);
      end;  TForm1 = class(TForm)
        Edit1: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        lbtotal: TLabel;
        Memo1: TMemo;
        procedure FormCreate(Sender: TObject);
        procedure FormKeyDown(Sender: TObject; var Key: Word;
          Shift: TShiftState);
      private
      public  end;var
      Form1: TForm1;implementation
    {$R *.dfm}
    Var
    MyArray:Array of Integer;
      DrawThread:TDrawThread;constructor TDrawThread.Create(NeedDrawCount: Integer);
    begin
      FNeedDrawCount:=NeedDrawCount;
      Inherited Create(False);
    end;procedure TDrawThread.DelOne;
    Var
    i:Integer;
    begin
      for i:=FRandomFoot to High(MyArray)-1 do
       MyArray[i]:=MyArray[i+1];
      SetLength(myarray,Length(Myarray)-1);
    end;procedure TDrawThread.DrawPrize;
    begin
      While(FHasDrawCount<FNeedDrawCount) do
      begin
       FRandomFoot:=Random(Length(MyArray));
        Synchronize(ShowDigtal);
      end;
    end;procedure TDrawThread.Execute;
    begin
      inherited;
      DrawPrize;
    end;procedure TDrawThread.ShowDigtal;
    begin
      form1.edit1.Text :=IntToStr(MyArray[FRandomFoot]);
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
    i:Integer;
    begin
    Randomize;
      //初始化数组
      SetLength(Myarray,100);//长度100
      for i:=Low(MyArray) to High(MyArray) do
       MyArray[i]:=10000+i;
      //创建线程
      DrawThread:=TDrawThread.Create(20);//从100个数中抽取10个不重复的数end;procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
       //不是按下的空白键盘 退出
    if not (Key in [32]) then Exit;
      if DrawThread.FHasDrawCount=DrawThread.FNeedDrawCount then Exit;
    DrawThread.FStop:= not DrawThread.FStop;
      //数字滚动停下来
      if DrawThread.FStop then
      begin
      DrawThread.Suspend;
       memo1.Lines.Add(Edit1.Text+',');
        Inc(DrawThread.FHasDrawCount);
        lbTotal.Caption :='已经抽出'+Inttostr(DrawThread.FHasDrawCount);
        DrawThread.DelOne;
      end
      else begin //开始新的滚动显示    DrawThread.Resume;
      end;
    end;end.
      

  2.   

    测试了楼主程序,运行正常,建议把
     //创建线程
      DrawThread:=TDrawThread.Create(20);//从100个数中抽取10个不重复的数
    写在FormShow事件中主线程虽修改了全局数组,但是在DrawThread.Suspend时修改的,应该不会出问题
      

  3.   

    找到一点问题
    procedure TDrawThread.DrawPrize;
    begin
      While(FHasDrawCount<FNeedDrawCount) do
      begin
        sleep(10);//加上这句
        FRandomFoot:=Random(Length(MyArray));
        Synchronize(ShowDigtal);
      end;
    end;