2009-12-15 22 views
5

Sự cố lạ. Có lẽ ai đó có thể cung cấp một số thông tin chi tiết.Xử lý được phát hành bị hỏng bằng cách nào đó?

  • Kịch bản 1. Tôi có một TBitmap trong bộ nhớ được viết trong khi các tính toán phức tạp diễn ra để tính toán màu của từng pixel. Thường xuyên như vậy (thường là sau mỗi đường ngang mà bitmap được lấp đầy), TBitmap được vẽ đến một hình ảnh trên một biểu mẫu (image1.Canvas.Draw (0, 0, TBitmap) Phần lớn thời gian này hoạt động tốt, nhưng tôi nhận thấy rằng nếu có nhiều calcs phức tạp chậm cho mỗi bitmap line (nói mất hơn 30 giây hoặc một phút để tính toán) thì biểu mẫu chính có một "nhấp nháy" tạm thời bằng cách nào đó xóa bitmap, vì vậy lệnh gọi image.draw chỉ rút ra mới nhất của dòng tính và các đường y đầu tiên được làm mờ đi trong bitmap. tôi đã nhận khoảng này bằng cách khóa bitmap trước khi tính toán.

  • Kịch bản 2. Đây là rắc rối chính. tôi viết thư này để một TMemoryStream Các tính toán diễn ra để tính toán từng giá trị pixel và sau đó mỗi giá trị pixel được ghi vào TMemoryStream với memstream.Write (bytevalue, 1) trong suốt quá trình. Vào cuối tất cả các tính toán, tôi lưu luồng vào một bitmap với memstream.SaveToFile ('whatever.bmp') và sau đó giải phóng luồng bằng memstream.Free. Nếu tính toán nhanh thì luồng sẽ tiết kiệm không có vấn đề gì kích thước (tôi đang làm thử nghiệm với kích thước 10000x10000).

Tôi thậm chí có thể cho biết tệp kết quả sẽ bị hỏng vì cửa sổ/biểu mẫu ứng dụng chính có một chút nhấp nháy giống như đang được sơn lại. Khi điều đó xảy ra, nó giống như mọi xử lý đối với bitmap và TMemoryStream bị giết/làm mới để dữ liệu hiện có bị hỏng.

Bất kỳ ý tưởng nào? Điều này thực sự sucks. Đặc biệt là khi mỗi hình ảnh có thể mất một giờ để tạo ra chỉ để thấy rằng khi nó kết thúc một cái gì đó trong nền đã xảy ra và bị hỏng bitmap hoặc TMemoryStream.

Có cách nào tôi có thể khóa xử lý TMemoryStream giống như tôi có thể với bitmap không? Điều đó có thể hữu ích. Hoặc một số tuyên bố để nói Delphi "Đừng gây rối với các đối tượng của tôi, ngay cả khi ứng dụng mất quá nhiều thời gian"

Hoặc không ai biết lý do cuối cùng bên trong Delphi gây ra điều này.

TMemoryStream được tạo bên trong quy trình thực hiện tất cả các phép tính như vậy là một đối tượng cục bộ. Với vấn đề bitmap bitmap là một biến toàn cục bên ngoài quy trình và nó đã xảy ra, vì vậy tôi không nghĩ đó là nguyên nhân.

Đây cũng là trong Windows 7, nhưng tôi nhận thấy vấn đề bitmap gốc trong Vista.

Cập nhật 1:

Xin lỗi vì không sử dụng những ý kiến, nhưng đó là restirction vào kích thước văn bản ...

Trong thư trả lời để Remy (và bất cứ ai khác đọc bài viết này) ...

Chỉ chuỗi đơn. Đối với bộ nhớ, nó hoạt động tốt cho độ phân giải 5000x5000 nếu tính toán nhanh, nhưng không thành công nếu các cals chậm.

Là một khuôn khổ cơ bản mã là dọc theo dòng của

SetupMemorystream; 
for y:=0 to height do 
    for x:=0 to width do 
     DoCalcs; 
     SetByteValue; 
    end; 
end; 
SaveStream; 

Nếu DoCalcs là tương đối nhanh chóng sau đó mọi việc suôn sẻ để lên kế hoạch. Nếu nó là chậm thì tôi nhận được tham nhũng TMemoryStream và bitmap kết quả luồng được lưu vào bị hỏng.

Điều này giống với sử dụng bộ nhớ TBitmap cho đến khi tôi phát hiện ra mình có thể khóa bitmap để dừng Delphi và/hoặc Windows phân bổ lại một xử lý mới cho nó khi nó muốn làm hỏng dữ liệu bên trong bitmap.

Đây là quá nhiều trùng hợp để không nghĩ rằng cùng một vấn đề không xảy ra với TMemoryStream và xử lý của nó.

Cập nhật 2:

Thêm một chút có lẽ hữu ích của thông tin.

Khi TMemoryStream lưu OK, tệp kết quả (đối với bitmap 5000x5000) có kích thước 75.000,054 byte.

Khi luồng đã lưu bị hỏng, nó dường như là một giá trị ngẫu nhiên (có kích thước từ khi tay cầm bị hỏng cho đến khi luồng được lưu). Kích thước mẫu đã là 22 MB và 9 MB.

Khi tôi xem các tập tin kết quả là một trình soạn thảo hex, nó cho thấy rằng sự khởi đầu của các tập tin là chính xác với các khối tiêu đề, nhưng đuôi kết thúc có được cắt ngắn bằng cách nào đó.

Điều này thật lạ lùng. Dù sao tôi hoàn toàn có thể chắc chắn tuôn ra một TMemoryStream sau khi một cuộc gọi SaveToFile và trước khi giải phóng nó?

+2

Mã của bạn có đa luồng không? Nếu không, thì không có cách nào tốc độ tính toán có thể là nguyên nhân những vấn đề bạn đã mô tả. Bạn có thể chỉ có mã lỗi đang ghi dữ liệu bị hỏng vào bitmap/stream. –

+0

Bạn luôn có thể nhận xét về các câu hỏi và câu trả lời của mình và mọi câu trả lời cho các câu hỏi bạn đã hỏi, ngay cả với 1 đại diện. Bạn cũng có thể chỉnh sửa câu hỏi của mình. –

+0

Luồng bộ nhớ chỉ là một đoạn bộ nhớ được bao bọc trong một lớp. VCL và RTL sẽ không gây rối với nó theo bất kỳ cách nào. Vì vậy, vấn đề của bạn phải ở trong mã ở đâu đó. – Runner

Trả lời

0

Thật khó để tìm ra lỗi như vậy bằng cách giả định những gì đang xảy ra. Bởi vì thao tác này rất dài nên tốn kém chỉ để lặp lại và chờ nếu tìm thấy lỗi.

Tôi đề nghị bạn đăng nhập mọi bước của quy trình. Bạn sẽ nhận được một bản ghi khổng lồ có thể, nhưng nó sẽ cho bạn thấy nơi mà mọi thứ đi sai. Lặp lại quá trình và cải thiện nhật ký của bạn, theo cách này bạn sẽ từ từ nhưng surelly tìm ra nguyên nhân của vấn đề.

1

Khi bạn giải phóng một luồng phim được sử dụng để ghi, cuộc gọi đóng tệp không được kiểm tra do lỗi. Vì vậy, viết của bạn có thể thất bại, có lẽ trên flushing ra các khối cuối cùng của tập tin lớn của bạn, và không có ngoại lệ sẽ được nâng lên.

Tôi bị ảnh hưởng bởi thời gian gần đây: số này nằm trong QC 80148. Tuy nhiên, không có nhiều việc bạn có thể làm, vì chức năng Windows CloseHandle cũng không thể trả về bất kỳ lỗi nào.

1
  1. Trước khi ghi mỗi byte vào luồng bộ nhớ, hãy đặt Dung lượng thành kích thước xấp xỉ của luồng bit để không thường xuyên kích thước lại bộ nhớ.điều ý chí tốc độ này lên

  2. Tôi nghĩ rằng bạn phải trừ đi 1 từ Height và Width trên vòng lặp for

Cheers

+0

+1, công suất sẽ thay đổi hiệu suất cho tốt hơn và các vòng lặp nhiều khả năng sẽ là 'cho y: = 0 đến height-1 do'. – skamradt

0

Bạn có thể sử dụng cuộc gọi API FlushFileBuffers(filestream.Handle) để tuôn ra một tFileStream, nhưng tôi đoán là cái gì khác đang xảy ra để gây tham nhũng ở nơi đầu tiên, có thể đơn giản như vòng lặp của bạn đi từ 0 đến chiều rộng thay vì 1 đến chiều rộng hoặc 0 đến width-1 ... khó nói mà không phân tích các thói quen đang làm để phổ biến luồng bộ nhớ của bạn.

1

Cảm ơn tất cả những người gợi ý. Các vòng lặp đã có chính xác 0 đến width-1 trong mã.

Vấn đề là các biến cho chiều rộng và chiều cao là các hình cầu đã được thay đổi ở nơi khác trong ứng dụng khi biểu mẫu chính được thay đổi kích thước (chúng thường theo dõi hình ảnh hiển thị trên màn hình), nhưng tôi đã sử dụng cùng các biến trong quy trình này để theo dõi chiều rộng và chiều cao bitmap của bộ nhớ, vì vậy khi chúng được thay đổi bên ngoài các vòng lặp đã làm hỏng và làm hỏng đầu ra, một lỗi của một vấn đề cần theo dõi. nên biết đó là lỗi của tôi chứ không phải vấn đề Delphi

Các vấn đề liên quan