Autor Beitrag
meisse
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Fr 17.06.11 15:20 
Hallo zusammen

Ich verwende den BackgroundWorker, um grosse Dateien (>100MB) über das Netzwerk zu beziehen und diese dann abzuspeichern. Gleichzeitig wird habe ich eine Progressbar
welche den Status des Files anzeigt. Leider wird aber während dem speichern das GUI und die Progressbar massiv blockiert. Die Daten werden folgendermassen bezogen:


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
if (waveformDataSource.HasRawData()) {
                                        int[] data = waveformDataSource.GetRawData(blk, startSample + offset, doNow);

                                        if (red.ReductionInfo.Type == DataReductionType.None || red.ReductionInfo.Factor == 1) {
                                            block.AppendRawData(data, 0, doNow);
                                        } else {
                                            List<int> reduced = red.Reduce(data);
                                            block.AppendRawData(reduced.ToArray(), 0, reduced.Count);
                                        }
                                    }



Der Aufruf von waveformDataSource.GetRawData() blockiert regelrecht den Gesamtbetrieb. Die Methode GetRawData greift auf eine C++ definierte Methode zurück welche folgendermassen definiert ist:


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
[DllImport(dllName)]
            public static extern ErrorCode TPC_GetRawData(int deviceIx, int boardAddress, int inputNumber,
                                                          int blockNumber,
                                                          int measurementNumber, UInt64 dataStart, int dataLength,
                                                          IntPtr /*(Int32*)*/ data);



Hat dies etwas mit dem Blockieren des GUI Threads zutun oder muss ich ganz wo anders suchen? Was für Zustände können den GUI THread noch blockieren? Muss dieser Methodenaufruf mit BeginInvoke aufgerufen werden damit dieser in einem separaten Thread läuft??

Mit freundlichen Grüssen
Christoph1972
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: Fr 17.06.11 15:30 
Bist du dir sicher das du den BW korrekt verwendest?

_________________
Gruß
Christoph
meisse Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Fr 17.06.11 15:45 
Folgendermassen wird der Backgroundworker verwendet:

ausblenden volle Höhe 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:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
BackgroundWorker _worker;

public void RunAsyncTpc5Writer(string filename, DataReductionInfo redInfo, DataReductionInfo redInfoECREvents) {
            _worker = new BackgroundWorker();
            _worker.WorkerReportsProgress = true;
            _worker.WorkerSupportsCancellation = true;

            _CurrentDoFilename = filename;
            _CurrentRedInfo = redInfo;
            _CurrentRedInfoECREvents = redInfoECREvents;

            _worker.DoWork += new DoWorkEventHandler(_worker_WriteTpc5Async);
            _worker.RunWorkerAsync();
        }


        private void _worker_WriteTpc5Async(object sender, DoWorkEventArgs e) {
            WriteTpc5Blocks(_CurrentDoFilename, _CurrentRedInfo, _CurrentRedInfoECREvents, null);
        }


private void WriteTpc5Blocks(string filename, DataReductionInfo redInfo, DataReductionInfo redInfoECREvents, BackgroundWorker worker) {
            //using (Tpc5File f = new Tpc5File(filename, FileMode.Create, FileAccess.ReadWrite)) {
            try {
.......

while (toGo > 0) {
                                    int doNow = (int)Math.Min(toGo, 1 * 1048576); // 1048576

                                    if (waveformDataSource.HasRawData()) {
                                        int[] data = inputSource.GetRawData(blk, startSample + offset, doNow);
                                        //int[] data = waveformDataSource.GetRawData(blk, startSample + offset, doNow);

                                        if (red.ReductionInfo.Type == DataReductionType.None || red.ReductionInfo.Factor == 1) {
                                            block.AppendRawData(data, 0, doNow);
                                        } else {
                                            List<int> reduced = red.Reduce(data);
                                            block.AppendRawData(reduced.ToArray(), 0, reduced.Count);
                                        }
............
}
}


Es wurde noch keine RunWorkerCompleted & ProgressChanged methoden implementiert.
Christoph1972
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: Fr 17.06.11 15:58 
user profile iconmeisse hat folgendes geschrieben Zum zitierten Posting springen:

Es wurde noch keine RunWorkerCompleted & ProgressChanged methoden implementiert.



Und wie soll das dann mit deiner Progressbar funktionieren ?

_________________
Gruß
Christoph
meisse Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Fr 17.06.11 15:58 
Ich habe nun folgendes programmier:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
if (waveformDataSource.HasRawData()) {
                                        int[] data = waveformDataSource.GetRawData(blk, startSample + offset, doNow);
                                        Thread.Sleep(100000);
                                        

                                        if (red.ReductionInfo.Type == DataReductionType.None || red.ReductionInfo.Factor == 1) {
                                            block.AppendRawData(data, 0, doNow);
                                        } else {
                                            List<int> reduced = red.Reduce(data);
                                            block.AppendRawData(reduced.ToArray(), 0, reduced.Count);
                                        }
                                    }


Nach dem die Daten via waveformDataSource.GetRawData() bezogen wurden (Es wird jeweils 1MB Daten Pro schleifendurchgang bezogen), pausiere ich den
BackgroundWorker für 100 Sekunden. Das Gui ist in dieser Zeit ohne Probleme zu bedienen. Also muss es irgendeinen Grund geben, warum der Aufruf
waveformDataSource.GetRawData() den GUI Thread so starch blockiert. Ich habe den BackgroundWorker schon an anderen Orten erfolgreich implementiert ohne
dass ich das GUI blockiert habe.
meisse Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Fr 17.06.11 16:03 
Natürlich wird so die progressbar nicht funktionieren. Dies habe ich noch nicht implementiert weil dieses Problem (GUI not resposinve) zum Vorschein gekommen ist und die Progressbar zum jetztigen Zeitpunkt noch nicht relevant ist.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Fr 17.06.11 16:38 
Das hört sich schon sehr merkwürdig an. Die höheren Versionen von VS2010 bieten aber einen Multithreading-Profiler, der dir genauer sagen sollte, womit sich der GUI-Thread da beschäftigt.

_________________
>λ=
meisse Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Fr 17.06.11 16:45 
Ok danke für den Hinweis. Ich werde mich mal damit befassen. Besitze VS 2010 Professional. Wenn ich weitere Hinweise habe oder Lösungen werde ich mich wieder melden.