-2

I want to convert the following code in C# to a parallel for. I searched the internet, but I could not find a proper way of doing that. I appreciate your helps.

Bitmap bmp = new Bitmap(1792, 2048);
for (int i = 0; i < 1792; i++)
{
    for (int j = 0; j < 2048; j++)
    {
        bmp.SetPixel(i,j,Color.FromArgb(100, 128, 128));
    }
}
  • 1
    You should probably avoid using multiple threads with `Bitmap`, since it isn't threadsafe. – Matthew Watson Sep 29 '17 at 12:02
  • here is the Microsoft documentation : https://msdn.microsoft.com/en-us/library/ff963552.aspx (found by typing `c# replace a for loop by parallel for` in google) – Pac0 Sep 29 '17 at 12:02
  • You can't. Bitmap is a marshalled GDI+ object.... – Matthew Whited Sep 29 '17 at 12:03
  • I assume that this is just representative code - otherwise you could just use `Graphics.FromImage(Bmp)` and a single call to `Graphics.FillRectangle()` – Matthew Watson Sep 29 '17 at 12:05
  • You should use lockbits and edit the bytes directly. – Matthew Whited Sep 29 '17 at 12:06
  • @Matthew Watson: yes, this is not the exact code I am trying to run. I have to retrieve the image data from an embedded device using UDP protocol and refresh a display under 60 ms. – Reza Ghochkhani Sep 30 '17 at 06:16
  • What format is the data from the device? If it is a bitmap data (uncompressed) you can just open the data from a memory stream. But based on your original question this duplicate question is still your fastest approach. – Matthew Whited Sep 30 '17 at 09:41
  • It looks like you are trying to read a video stream from a device over a network connection. Network latency alone can eat the majority of your time limit. (there is a reason network video stream lag or stutter.) – Matthew Whited Sep 30 '17 at 09:46
  • @Matthew Whited: no it is not bitmap, it sends 2 bytes per pixel (from 0 to 56536) and I have to read two consecutive bytes and convert them to this number and then map them to 8-bit, or directly display the int number!!! I don't know. I may be able to use pointers, but they are not very decent in C#. – Reza Ghochkhani Sep 30 '17 at 21:37
  • That's 0 to 65536. You are receiving at a 16bit bitmap. Go look at that example from the page i marked as duplicate and change the PixelFormat to 16bit and just use the first two pointers. (of just dump it to a memory stream and open the bitmap using the correct resolution and bit depth. – Matthew Whited Sep 30 '17 at 21:55

1 Answers1

0

You should only replace the outer loop:

Bitmap bmp = new Bitmap(1792, 2048);
Parallel.For(0, 1792, i =>
{
    for (int j = 0; j < 2048; j++)
    {
        bmp.SetPixel(i,j,Color.FromArgb(100, 128, 128));
    }
});

This assumes it is safe to call SetPixel concurrently, of which I'm not quite sure.

Henrik
  • 23,186
  • 6
  • 42
  • 92
  • Bitmap is not thread thread safe – Matthew Whited Sep 29 '17 at 12:04
  • @MatthewWhited Thanks for the info. I already mentioned this posibility in my answer. – Henrik Sep 29 '17 at 12:05
  • Using `Parallel.For` will cause this to run even slower because of the internal locks in `.SetPixel(...)` – Matthew Whited Sep 29 '17 at 12:09
  • Sure, in this case you wouldn't use `Parallel.For`. My point is: even if it makes sense to use `Parallel.For`, one would usually only use it for the outer loop. – Henrik Sep 29 '17 at 12:16
  • 1
    This is clearly an [x/y problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). The correct solution to the actual problem of OP is in the duplicate-marked answer. – Pac0 Sep 29 '17 at 12:31
  • https://stackoverflow.com/questions/8807330/nested-parallel-for-loops-speed-and-performance – Matthew Whited Sep 29 '17 at 14:01
  • Thanks you all guys for giving such good suggestions. Yes you are right, the Parallel.For works even slower. I do not know what to do. I need to refresh a display with a changing image under 60ms. I really do not know how to make it happen. Do you think C# can do that? – Reza Ghochkhani Sep 30 '17 at 05:53