Autor Beitrag
JustTom
Hält's aus hier
Beiträge: 1



BeitragVerfasst: Fr 25.07.08 15:47 
Hallo,

ich habe ein Problem mit meinem Programm in dem ich Bilder verarbeiten muss. Da die Verarbeitung der Bilder etwas komplexer ist, und man mit dem Programm weiterarbeiten können sollte, habe ich für die Bildverarbeitung einen Backgroundworker verwendet.

Im Window_Loaded():
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
                MessageBox.Show("Canceled");
            }
            else
            {
                image1.Source = (ImageSource)e.Result;
            }
}


ausblenden C#-Quelltext
1:
2:
3:
4:
void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
      progressBarStatus.Value = e.ProgressPercentage;
}


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
            BackgroundWorker worker = sender as BackgroundWorker;

            e.Result = ReadObjects((string)e.Argument, worker, e);

            if (worker.CancellationPending)
            {
                e.Cancel = true;
            }
}


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
RenderTargetBitmap ReadObjects(string path, BackgroundWorker worker, DoWorkEventArgs e)
        {
            BitmapImage bitmapImg = null;
            DrawingVisual drawingVisual = null;
            DrawingContext drawingContext = null;
            RenderTargetBitmap rtb = null;

            drawingVisual = new DrawingVisual();
            bitmapImg = new BitmapImage();

            if (worker.CancellationPending)
            {
                e.Cancel = true;
            }
            else
            {
                    drawingContext = drawingVisual.RenderOpen();
                    // In drawingContext zeichnen..........
                    drawingContext.Close();
                    sqlConn.Close();
            }
            // drawingVisual rendern
            rtb = new RenderTargetBitmap(256020489696, PixelFormats.Pbgra32);
            rtb.Render(drawingVisual);
            rtb.Freeze();

            return rtb;
}


Also, das Programm in gekürzter Version.

Das Programm funktioniert auch, also bei einem Buttonclick wird der Backgroundworker aufgerufen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
try
{
    if (!backgroundWorker.IsBusy)
    {
        // Start the asynchronous operation.
        backgroundWorker.RunWorkerAsync(lboxEingang.Items[0].ToString());
     }
}
catch (Exception e)
   {
        MessageBox.Show(e.Message);
    }
}


Wenn ich jetzt aber zB im Windows auf ein anderes Programm wechsle und dann wieder zurückgehe zu meinem Programm, dann hängt dieses. kA warum das so ist? Wenn ich das Render.Open()... usw in ReadObjects() weglasse, dann hängt es komischerweise nicht?

Weiß jemand wo mein Fehler liegt?
Hoffe ich hab das Programm jetzt trotz der Kürzung, vollständig gepostet.

Gruß,
Tom

// Edit: Es liegt definitiv an folgendem:
ausblenden C#-Quelltext
1:
drawingContext = drawingVisual.RenderOpen();					


Jemand eine Ahnung/Idee?

Moderiert von user profile iconChristian S.: Highlight- durch C#-Tags ersetzt
jpkleinau
Hält's aus hier
Beiträge: 16

Vista
XAML, C#
BeitragVerfasst: Mo 06.10.08 17:46 
Der Grund ist ein ganz einfacher: die Message Pump in Vista ist immer noch eine Windows Message Pump. Wenn du von deinen Background Workers in die Oberfläche eingreifst, so wirst du automatisch einen Konflikt mit der Message Pump erzeugen. So lange du keine konfliktreichen Messages erzeugst, geht alles gut - aber wehe wenn du die schlafenden Hunde weckst ;-)

Siehe auch dazu Channel 9 channel9.msdn.com/fo.../17256-Message-Pump/

Du kannst die Bilder in einem Zwischenspeicher ablegen, den du sperren kannst. Dann kann von der Message Pump (also der GUI) und deinen Workern munter zugegriffen werden.