Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 合并绘制导致线程位图绘制_Multithreading_Delphi_Bitmap - Fatal编程技术网

Multithreading 合并绘制导致线程位图绘制

Multithreading 合并绘制导致线程位图绘制,multithreading,delphi,bitmap,Multithreading,Delphi,Bitmap,我想加快绘制位图的速度,因此我设计了一个类似的类。完成局部图像的单独绘制后,我希望在Thread.done过程中合并所有图像 我的代码是这样的 type TbmpthreadForm = class(TForm) ..... THreadImage: TImage; procedure Button_threadstartClick(Sender: TObject); procedure FormCreate(S

我想加快绘制位图的速度,因此我设计了一个类似的类。完成局部图像的单独绘制后,我希望在Thread.done过程中合并所有图像 我的代码是这样的

    type
      TbmpthreadForm = class(TForm)
        .....
        THreadImage: TImage;
        procedure Button_threadstartClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        { Private-Deklarationen }
        procedure ThreadDone(Sender: TObject);
      public
        { Public-Deklarationen }
        fserver, fdatabasename, ftablename: String;
        global_thread_counter: Integer;
        XPixel, YPixel: Integer;
        Masterbitmap: TBitmap;
      end;

    var
      bmpthreadForm: TbmpthreadForm;

    implementation

    {$R *.dfm}

    procedure TbmpthreadForm.ThreadDone(Sender: TObject);
    begin
      dec(global_thread_counter);
      MyStatusBar.SimpleText := 'Thread Count ->' + IntToStr(global_thread_counter);

      Masterbitmap.Canvas.Lock;
      with (Sender as TPaintBitmapThread) do
      begin
        bitblt(Masterbitmap.Canvas.handle, 0, 0, XPixel, YPixel,
          bitmap.Canvas.handle, 0, 0, srcand);
        THreadImage.Picture.Bitmap.Assign(Masterbitmap);
        // lets see local tthread intermediate results  and save it to HD
        THreadImage.Picture.Bitmap.SaveToFile('c:\temp\myimage' + IntToStr(Index)
  + '.bmp');
      end;
      Masterbitmap.Canvas.UnLock;

      if (global_thread_counter = 0) then
      begin
         ...
      end;
    end;
procedure TbmpthreadForm.Button_threadstartClick(Sender: TObject);
var
     ..... 
begin

  index_max := 2000000;
  threadCounter := 10;
  Indexdelta := round(index_max / threadCounter);

  ///
  ///
  ....
  Masterbitmap.Width := XPixel;
  Masterbitmap.Height := YPixel;

  for i := 0 to threadCounter - 1 do
  begin
    n := i * Indexdelta;
    m := (i + 1) * Indexdelta;
    //  just a test sql string .... 
    sqlstr := 'select * from  Mytable  where objectindex <' + IntToStr(m) +
      ' and Objectindex >' + IntToStr(n);

    aPaintBitmapThread := TPaintBitmapThread.Create(XPixel, YPixel, ......   , fserver, fdatabasename, ftablename,
      sqlstr, i);
    aPaintBitmapThread.OnTerminate := ThreadDone;
    Memo1.Lines.Add('start thread->' + IntToStr(i));
    inc(global_thread_counter);
  end;

end;
Thread.done设计遵循前面的主题,因此 由于生成的图像/主位图与运行时看起来有点不同,我想我的方法不是线程安全设计,即将线程bmp内容复制到VCL mainform中的主位图中, 我看不到我的代码有任何错误,有什么问题吗

补充问题

Q1:TPaintBitmapThread中的fbitmap是在Thread.create过程中创建的,对于TAdoconnection,我找到了注释,它应该在Thread.execute中创建。位图也必须这样做吗

问题2:附加的图像显示线程对imageBitmap的预期结果,以及通过THreadImage.Picture.Bitmap.SaveToFile命令看到的实际图像结果

    bitblt(Masterbitmap.Canvas.handle, 0, 0, XPixel, YPixel,
      bitmap.Canvas.handle, 0, 0, srcand);
您显式地调用了Masterbitmap.Canvas.Lock,但是您没有调用bitmap.Canvas.Lock,因此您可以在此调用中随时释放画布句柄

另外,您需要考虑GDI本身中的线程安全性:所有的GDI对象在不同线程之间的共享都应该不惜一切代价避免。例如,如果您同时在两个不同的设备上下文中选择位图,但在不同的线程中,您可能会在GDI本身中遇到问题


请注意,旧版本的delphi无法防止共享缓存句柄字体、画笔和笔句柄缓存在全局列表中。如果我没记错的话,这是在XE3 service pack中修复的


简而言之,如果你真的需要多线程,我会考虑完全避免TCANVAS和TBITMAP。通过这种方式,多线程安全更容易实现

告诉我们更多关于XPixel和YPixel的信息。为什么我们不能有一个完整的程序?完整的代码相当长;Xpixel和ypixel是线程内位图的大小,我也对主位图使用相同的大小。使用我的bitblt Com,我只是将本地线程bmp复制到主bmpI中,我不想看到您的完整代码。我想看到一个完整的程序来说明这个问题。SSCCE.SSCCE很难创建;可能是q1我可以得到更多的帮助或者额外的奇怪的调试结果,从单个线程保存的位图也会显示完整的数据/图像。它应该只包含一定数量的图纸;我在上面的源代码中添加了调试行:在位图Delphi中绘制异步线程,由Remy Lebeau回答;是否也需要关键部分?我是否正确理解了这里的解决方案?字体、画笔和笔柄缓存在全局列表中。->这似乎是一个很好的输入,即使XE5也显示出相同的错误行为。查看更新的问题猜测这是我问题的真正根本原因请注意,旧版本的delphi无法防止共享缓存句柄字体、笔刷和笔句柄缓存在全局列表中。如果我没记错的话,这是在XE3 service pack中修复的。