2017-09-02 272 views
0

我发现很多关于Backgroundworker更新进度条的信息,并且我已经编写了许多版本的代码。但是在升级应用程序运行的时候,没有任何版本更新进度条。这里是我已经使用了DoWork的处理程序版本之一:如何获得进度条更新在执行后台工作中运行的应用程序

void worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     updater.updater(); 

     int percents = 0; 

     // Progress bar 
     int total = 57; 

     for (int i = 0; i <= total; i++) 
     { 
      System.Threading.Thread.Sleep(100); 
      percents = (i * 100)/total; 
      bw.ReportProgress(percents, i); 
     } 

如果我运行更新(我的应用程序)之前ReportProgress(如图所示),更新运行完全,然后进度条的更新从0到100%。如果我在ReportProgress调用之后放置更新程序,则会运行进度栏,然后运行更新程序。如果我用更新程序替换Thread.Sleep行,它将以进度条的0%间隔运行。

实际上是否有可能在后台工作中执行长时间运行的应用程序时更新进度栏?这就是backgroundworker声称的MSDN页面,但他们实际展示的是它运行一系列简短流程(睡眠)而不是一个漫长的过程。我在线上找到的大多数示例都使用这种格式,因此没有提到没有分段到ReportProgress部分的较长时间的运行过程。

我很想知道背景工作者是否能够做到这一点,或者这是一些其他线程类型解决方案的工作。

谢谢!

在看到Tim的回答后,我试图为进度条进度实现EventArg和Handler。

public class FWupdater 
{ 
    public string comPort; 
    public int percentage; 
    public State state; 
    public string path; 
    public const int ACK = 0x79; 
    public const int NACK = 0x1F; 

    public class PBProgressEventArgs : EventArgs 
    { 
     private int prog; 

     public int progress 
     { 
      set { prog = value; } 
      get { return this.prog; } 
     } 
    } 

    public class PBProgress 
    { 
     public event PBProgressHandler Progress; 
     public delegate void PBProgressHandler(PBProgress p, PBProgressEventArgs e); 
     public void Start() 
     { 
      if (Progress != null) 
      { 
       PBProgressEventArgs progressUpdate = new PBProgressEventArgs(); 
       progressUpdate.progress = 0; 
       Progress(this, progressUpdate); 
      } 
     } 
    } 

然后在主程序中创建一个实例,以便背景工作者可以看到它。

PBProgress progUpdater = new PBProgress(); 

但我无法从backgroundWorker看到DoWork方法中的进度百分比。

包含更新器代码。

public void updater() 
    { 
     // Create a new SerialPort object. 
     SerialPort _serialPort; 
     _serialPort = new SerialPort(comPort, 115200, Parity.Even, 8, StopBits.One); 

     // for state machine 
     bool _continue = true; 

     try 
     { 
      _serialPort.Open(); 

      if (_serialPort.IsOpen) 
      { 
       Console.WriteLine(""); 
       Console.WriteLine("Serial Port is Open"); 
       Console.WriteLine(""); 
      } 
      else 
      { 
       MessageBox.Show("Serial Port is not open. Choose another port."); 
      } 
     } 
     catch (UnauthorizedAccessException ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
     catch (ArgumentOutOfRangeException ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
     catch (ArgumentException ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
     catch (IOException ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
     catch (InvalidOperationException ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 


     // Move through states until upgrade is complete 
     while (_continue) 
     { 
      switch (state) 
      { 
       case State.NORMAL: 

        // Beginning state for instance of upgrader 

        break; 

       case State.WAITING_TO_UPGRADE: 

        SetUpComm(_serialPort); 
        state = State.ERASING_FIRMWARE; 
        break; 

       case State.ERASING_FIRMWARE: 

        EraseFlashMemory(_serialPort); 
        state = State.UPGRADING_FIRMWARE; 
        break; 

       case State.UPGRADING_FIRMWARE: 

        WriteNewAppToFlash(_serialPort); 
        state = State.UPGRADE_COMPLETE; 
        break; 

       case State.UPGRADE_COMPLETE: 

        JumpToNewApp(_serialPort); 
        _continue = false; 
        _serialPort.Close(); 
        break; 

       default: 
        break; 

      } // end SWITCH (state) 

     } // end WHILE (_continue) - main loop 

    } // end public void updater() 
     // 

    // ---- METHODS ------------------- 



    public void SetUpComm(SerialPort _serialPort) 
    { 
     int byte_read = 0x00; 
     var sevenF = new byte[] { 0x7F }; 

     // Send 0x55 and 0xAA to peripheral input to execute SwitchToBootloader() 
     var byte1 = new byte[] { 0x55 }; 
     var byte2 = new byte[] { 0xAA }; 

     _serialPort.Write(byte1, 0, 1); 
     _serialPort.Write(byte2, 0, 1); 

     // If in bootloader mode, where the boot pins on the board are set, 
     // the device will be looking to receive 0x7F to establish contact with the host. 
     // In this case, the bytes to trigger boot load from inside the firmware will be 
     // ignored and the following 0x7F will serve to trigger comm set-up . 

     // Wait for acknowledge byte from USART 
     while (byte_read != ACK) 
     { 
      // Write "7F" to start communicating with Bootloader 
      _serialPort.Write(sevenF, 0, 1); 
      Thread.Sleep(100); 

      // read ACK byte after parameters set and bootloader running 
      byte_read = _serialPort.ReadByte(); 
     } 
    } 


    public void EraseFlashMemory(SerialPort _serialPort) 
    { 
     int byte_read = 0; 
     var ff = new byte[] { 0xFF }; 



     Console.WriteLine("Erasing flash memory..."); 
     Console.WriteLine(""); 

     /* NOTE: the ERASE COMMAND is not supported by this device, use EXTENDED ERASE */ 

     // Send 0x44 and 0xBB (extended erase memory command), see AN3155 
     var exeraseMem = new byte[] { 0x44 }; 
     var bb = new byte[] { 0xBB }; 

     _serialPort.Write(exeraseMem, 0, 1); 
     _serialPort.Write(bb, 0, 1); 

     // Receive ACK byte 
     byte_read = _serialPort.ReadByte(); 

     if (byte_read == NACK) 
     { 
      //Console.WriteLine("NACK received for ERASE MEMORY start"); 
      //Console.WriteLine(""); 
     } 
     //// end sending EXTENDED ERASE COMMAND 

     //--------------------------------------- 
     // Global erase (send 0xFFFF, and 0x00) 
     //--------------------------------------- 
     //var globalErase = new byte[] { 0x00 }; 
     //_serialPort.Write(ff, 0, 1); 
     //_serialPort.Write(ff, 0, 1); 
     //_serialPort.Write(globalErase, 0, 1); 

     // Erase all but the first page (16k) 
     // send number of pages to erase, msb first [11 pages, leaving page 0] 
     // *ALERT* send 10 pages (N) to erase 11, for some reason it erases N + 1, whatever... 
     var num_pages_msb = new byte[] { 0x00 }; 
     var num_pages_lsb = new byte[] { 0x0A }; 
     _serialPort.Write(num_pages_msb, 0, 1); 
     _serialPort.Write(num_pages_lsb, 0, 1); 

     // send page numbers, 2 bytes each, msb first 

     // PAGE 1 
     var page01_msb = new byte[] { 0x00 }; 
     var page01_lsb = new byte[] { 0x01 }; 
     _serialPort.Write(page01_msb, 0, 1); // 0 
     _serialPort.Write(page01_lsb, 0, 1); // 1 

     // PAGE 2 
     var page02_lsb = new byte[] { 0x02 }; 
     _serialPort.Write(page01_msb, 0, 1); // 0 
     _serialPort.Write(page02_lsb, 0, 1); // 2 

     // PAGE 3 
     var page03_lsb = new byte[] { 0x03 }; 
     _serialPort.Write(page01_msb, 0, 1); // 0 
     _serialPort.Write(page03_lsb, 0, 1); // 3 

     // PAGE 4 
     var page04_lsb = new byte[] { 0x04 }; 
     _serialPort.Write(page01_msb, 0, 1); // 0 
     _serialPort.Write(page04_lsb, 0, 1); // 4 

     // PAGE 5 
     var page05_lsb = new byte[] { 0x05 }; 
     _serialPort.Write(page01_msb, 0, 1); // 0 
     _serialPort.Write(page05_lsb, 0, 1); // 5 

     // PAGE 6 
     var page06_lsb = new byte[] { 0x06 }; 
     _serialPort.Write(page01_msb, 0, 1); // 0 
     _serialPort.Write(page06_lsb, 0, 1); // 6 

     // PAGE 7 
     var page07_lsb = new byte[] { 0x07 }; 
     _serialPort.Write(page01_msb, 0, 1); // 0 
     _serialPort.Write(page07_lsb, 0, 1); // 7 

     // PAGE 8 
     var page08_lsb = new byte[] { 0x08 }; 
     _serialPort.Write(page01_msb, 0, 1); // 0 
     _serialPort.Write(page08_lsb, 0, 1); // 8 

     // PAGE 9 
     var page09_lsb = new byte[] { 0x09 }; 
     _serialPort.Write(page01_msb, 0, 1); // 0 
     _serialPort.Write(page09_lsb, 0, 1); // 9 

     // PAGE 10 
     var page10_msb = new byte[] { 0x01 }; // 1 
     var page10_lsb = new byte[] { 0x00 }; // 0 
     _serialPort.Write(page10_msb, 0, 1); 
     _serialPort.Write(page10_lsb, 0, 1); 

     // PAGE 11 
     _serialPort.Write(page10_msb, 0, 1); // 1 
     _serialPort.Write(page01_lsb, 0, 1); // 1 

     // checksum = A 
     _serialPort.Write(num_pages_lsb, 0, 1); 

     // Receive ACK byte 
     byte_read = _serialPort.ReadByte(); 


     bw.ReportProgress(20); 

     if (byte_read == NACK) 
     { 
      //Console.WriteLine("NACK received for ERASE MEMORY completed"); 
      //Console.WriteLine(""); 
     } 
    } 
    // -- end EXTENDED ERASE MEMORY -------------------------------------------------- 


    public void WriteNewAppToFlash(SerialPort _serialPort) 
    { 
     // For testing 
     int blockCount = 0; 

     int byte_read = 0; 
     long checksum = 0; 
     var ff = new byte[] { 0xFF }; 

     // ------------------------------------------------------------------------------ 
     // -------- WRITE MEMORY -------------------------------------------------------- 
     // ------------------------------------------------------------------------------ 

     // for Address 
     int baseAddress = 0x08008000; 
     int offset = 0; 

     // for string from HEX file 
     string line; 
     string[] lineBuffer = new string[16]; 
     int lineCount = 0; 
     int length; 
     int type; 
     int hexChecksum = 0; 

     bool sendAddress = true; 

     int counter = 0;   // Counting the number of lines in the file 
     int byteCounter = 0;  // Counting nmumber of bytes in the current block 

     // Create byte array with 256 bytes 
     byte[] buffer256 = new byte[256]; 

     // Read the file and process one line at a time 
     System.IO.StreamReader file = new System.IO.StreamReader(path); 
     while ((line = file.ReadLine()) != null) 
     { 
      // Store line into a line buffer. This will allow reprocessing of all lines 
      // in a block if there is an error sending a block of 256 bytes below 
      if(line[8] == '0') 
      { 
       lineBuffer[lineCount++] = line; 
      } 

      // Send WRITE COMMAND and the next address every 256 bytes 
      if (sendAddress == true) 
      { 
       /* 
    ------------------------------------------------------------------------------------------------------- 
        SEND WRITE COMMAND 
    -----------------------------------------------------------------------------------------------------*/ 

       do 
       { 
        // Send WRITE command - 0x31 and 0xCE 
        var writeMem = new byte[] { 0x31 }; 
        var ce = new byte[] { 0xCE }; 

        _serialPort.Write(writeMem, 0, 1); 
        _serialPort.Write(ce, 0, 1); 

        // Receive ACK byte 
        byte_read = _serialPort.ReadByte(); 

       } while (byte_read != ACK); 

       // -- end SEND 0x31 and 0xCE and wait for ACK ----------------------------------------- 

       /* 
    ------------------------------------------------------------------------------------------------------- 
       SEND CURRENT ADDRESS AND CHECKSUM TO FLASH MEMORY 
    -----------------------------------------------------------------------------------------------------*/ 

       Byte[] currentAddr = BitConverter.GetBytes(baseAddress + offset); 

       // Increment offset by 0x100 (256 bytes) 
       offset = offset + 0x00000100; 

       // Reset Checksum and XOR address 
       checksum = 0; 
       foreach (byte b in currentAddr) 
       { 
        checksum ^= b; 
       } 

       Byte[] cksum = BitConverter.GetBytes(checksum); 

       // Send address, MSB first, LSB last 
       _serialPort.Write(currentAddr, 3, 1); 
       _serialPort.Write(currentAddr, 2, 1); 
       _serialPort.Write(currentAddr, 1, 1); 
       _serialPort.Write(currentAddr, 0, 1); 

       // Send checksum of address bytes 
       _serialPort.Write(cksum, 0, 1); 

       // Receive ACK byte 
       byte_read = _serialPort.ReadByte(); 

       if (byte_read == NACK) 
       { 
        // Handle 
       } 
       // -- end addr or increment --------------------------------------------------------- 

       sendAddress = false; 

       // Send number of bytes, always 256, the last group will be padded with 0xFF 
       _serialPort.Write(ff, 0, 1); 

      } // end IF for WRITE COMMAND and ADDRESS 


      /* FIRST CHARACTER in HEX FILE 
       The colon indicates the start of a "record" 
       Remove colon from beginning of string            */ 
      line = line.Substring(1, line.Length - 1); 

      // Create byte array from string for whole line from HEX file 
      var bytes = GetBytesFromByteString(line).ToArray(); 

      // Identify RECORD TYPE of HEX line [byte 4] 
      type = bytes[3]; 

      /* Next TWO CHARACTERS 00-data      03-start segment address 
       in HEX FILE are  01-EOF      04-extended linear address 
       the record type:  02-extended segment address 05-start linear address  */ 

      // BLOCK WRITE TO MEMORY 
      if (type == 0) 
      { 
       // Length of line is stored at byte 0, in this case 0x10, or 16 bytes of data 
       length = bytes[0]; 

       // Add data from current line to buffer of 256 bytes 
       for (int i = 0; i < length; i++) 
       { 
        // Stuff all bytes from line into buffer of 256 bytes 
        buffer256[byteCounter++] = bytes[4 + i]; 

        // Add byte to checksum 
        hexChecksum ^= bytes[4 + i]; 
       } 

       // When buffer is full, send block of 256 bytes and checksum, reset variables for next block 
       if (byteCounter >= 255) 
       { 

        // Convert checksum to a byte value 
        hexChecksum = hexChecksum^0xFF; 
        byte csByte = Convert.ToByte(hexChecksum); 
        Byte[] csByte_arr = BitConverter.GetBytes(csByte); 

        // Send byte array 
        _serialPort.Write(buffer256, 0, 256); 

        // For testing 
        // Console.WriteLine("block number [{0}]", ++blockCount); 

        //send checksum 
        _serialPort.Write(csByte_arr, 0, 1); 

        //Receive ACK byte 
        byte_read = _serialPort.ReadByte(); 
        Console.WriteLine("block/ACK = [{0}] | {1}", ++blockCount, byte_read); 

        while (byte_read != ACK) 
        { 
         Array.Clear(buffer256, 0, buffer256.Length); 
         hexChecksum = 0; 
         lineCount = 0; 

         // reprocess the previous 16 lines stored in the line buffer 
         for (int j = 0; j < 16; j++) 
         { 
          line = lineBuffer[j]; 

          line = line.Substring(1, line.Length - 1); 
          var bytesLocal = GetBytesFromByteString(line).ToArray(); 

          length = bytesLocal[0]; 
          for (int i = 0; i < length; i++) 
          { 
           buffer256[byteCounter++] = bytesLocal[4 + i]; 
           hexChecksum ^= bytesLocal[4 + i]; 
          } 
         } 

         // Convert checksum to a byte value 
         hexChecksum = hexChecksum^0xFF; 
         byte csByteLocal = Convert.ToByte(hexChecksum); 
         Byte[] csByte_arrLocal = BitConverter.GetBytes(csByteLocal); 

         // Send byte array 
         _serialPort.Write(buffer256, 0, 256); 

         //send checksum 
         _serialPort.Write(csByte_arrLocal, 0, 1); 

         //Receive ACK byte 
         byte_read = _serialPort.ReadByte(); 
         Console.WriteLine("block/ACK = [{0}] | {1}", ++blockCount, byte_read); 
        } 

        // Clear buffer, reset byte count, clear checksum, set flag to send write cmd/send new addr 
        Array.Clear(buffer256, 0, buffer256.Length); 
        byteCounter = 0; 
        hexChecksum = 0; 
        lineCount = 0; 
        sendAddress = true; 
       } 

      } // end BLOCK WRITE TO MEMORY 

      else if (type == 1) // Marker for end of file 
      { 
       while (byteCounter != 0) 
       { 
        // Add 0xFF to the remaining bytes in this last block of 256 
        buffer256[byteCounter++] = 0xFF; 

        // Add byte to checksum 
        hexChecksum ^= 0xFF; 

        if (byteCounter >= 255) 
        { 
         byteCounter = 0; 

         // Convert checksum to a byte value 
         hexChecksum = hexChecksum^0xFF; 
         byte csByte = Convert.ToByte(hexChecksum); 
         Byte[] csByte_arr = BitConverter.GetBytes(csByte); 

         // Send byte array 
         _serialPort.Write(buffer256, 0, 256); 

         // For testing 
         // Console.WriteLine("block number [{0}]", ++blockCount); 

         //send checksum 
         _serialPort.Write(csByte_arr, 0, 1); 

         //Receive ACK byte 
         byte_read = _serialPort.ReadByte(); 
         Console.WriteLine("block/ACK = [{0}] | {1}", ++blockCount, byte_read); 

         if (byte_read == NACK) 
         { 
          // ?? 
         } 
        } 
       } 
      } 
      // end ELSE if TYPE == 1 

      counter++; 
     } // end WHILE loop for loading hex file 

     file.Close(); 

     // For testing 
     // Console.WriteLine("File is closed."); 
     // System.Console.WriteLine("There were {0} lines.", counter); 
     // Console.WriteLine(""); 

     // -- end WRITE MEMORY ------------------------------------------------------ 

    } // end WriteNewAppToFlash 



    private void handleAppSerialError(IOException exc) 
    { 
     throw new NotImplementedException(); 
    } 

    private void raiseAppSerialDataEvent(byte[] received) 
    { 
     throw new NotImplementedException(); 
    } 

    public void JumpToNewApp(SerialPort _serialPort) 
    { 
     int byte_read = 0; 
     long checksum = 0; 
     var ff = new byte[] { 0xFF }; 
     int baseAddress = 0x08000000; 


     // Jumps to flash memory 0x08000000, where the sector 0 code will perform a normal startup 

     // Send 0x21 (GO) and complement 0xDE 
     var go = new byte[] { 0x21 }; 
     var de = new byte[] { 0xDE }; 

     while (byte_read != 0x79) 
     { 
      _serialPort.Write(go, 0, 1); 
      _serialPort.Write(de, 0, 1); 

      // Receive ACK byte 
      byte_read = _serialPort.ReadByte(); 

      if (byte_read == NACK) 
      { 
       //Console.WriteLine("NACK received for GO COMMAND start"); 
       //Console.WriteLine(""); 
      } 
     } 

     // -- end SEND GO COMMAND and wait for ACK ----------------------------------------- 


     Byte[] startAddr = BitConverter.GetBytes(baseAddress); 

     // Reset Checksum and XOR address 
     checksum = 0; 
     foreach (byte b in startAddr) 
     { 
      checksum ^= b; 
     } 

     Byte[] cheksum = BitConverter.GetBytes(checksum); 

     // Send first byte (msb) of address 
     _serialPort.Write(startAddr, 3, 1); 

     // Send second byte of address 
     _serialPort.Write(startAddr, 2, 1); 

     // Send third byte of address 
     _serialPort.Write(startAddr, 1, 1); 

     // Send last byte (lsb) of address 
     _serialPort.Write(startAddr, 0, 1); 

     _serialPort.Write(cheksum, 0, 1); 

     Thread.Sleep(20); 
     // Receive ACK byte 
     byte_read = _serialPort.ReadByte(); 

    } // end JUMPTONEWAPP 


    // Converts a string to a byte array 
    public static IEnumerable<byte> GetBytesFromByteString(string str) 
    { 
     for (int index = 0; index < str.Length; index += 2) 
     { 
      yield return Convert.ToByte(str.Substring(index, 2), 16); 
     } 
    } 

    protected void AssertOpenPort() 
    { 
     //   if(!IsOpen) 
     //    throw new InvalidOperationException("Serial Port is not open"); 
    } 

} // end public class FWupdater 
+3

请包括updater.updater()的源代码;''ReportProgress''必须从**那个**方法中调用。 – mjwills

+2

你的代码清楚地表明'updater.updater()'必须在其他事情发生之前完成。您的当前代码永远不会在更新程序运行时更新进度,因为更新程序必须先完成才能更新进度。您的更新程序将不得不支持某些方法来显示它在过程中的位置,以便能够显示进度。 –

+0

@mjwills - 试图从Updater更新ReportProgress,但没有更新已完成的百分比。是否应该使用相同的BackgroundWorker,或者应该是不同的实例。我不知道如何管理班级间的沟通。 – Gordon

回答

2

问题是在升级过程中得到更新,因此发送您正在测试的工作的程序中的百分比变化是有意义的。我缺少的部分是由@mjwills提供的 - 将BackgroundWorker作为参数传递给updater允许我从updater调用ReportProgress,并按照我的意愿增加百分比值。

我使用的BackgroundWorker(bw)设置非常像MSDN中所示。以下是我在表单类中放置的bw的方法。

 BackgroundWorker bw = new BackgroundWorker(); 

然后一个按钮点击事件(示出了方法的端部),当客户端具有的COM端口和升级选择的文件,其次是体重的方法。

  bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
      bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); 
      bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 

      bw.WorkerReportsProgress = true; 

      bw.RunWorkerAsync(); 

      pbar.Maximum = 100; 
      pbar.Minimum = 0; 
      pbar.Value = 0; 

      // Percentage will be added to the end of this line during the upgrade 
      updateMsg.Content = "Upgrade in progress...  "; 
     } 
    } 

    void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker bw = sender as BackgroundWorker; 
     updater.updater(bw); 
    } 

    void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     pbar.Value = e.ProgressPercentage; 
     updateMsg.Content = String.Format("Upgrade in progress... {0} %", e.ProgressPercentage); 
    } 

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     updateMsg.Content = "Upgrade Complete. Exit window to proceed..."; 
    } 

在更新器()侧,定义一个百分比变量:

public int percentage; 

添加BackgroundWorker的作为参数:

public void updater(BackgroundWorker bw) { <code> } 

然后调用ReportProgress以更新的ProgressPercentage事件bw_ProgressChanged方法。开始为0%,增加的百分比变量:

bw.ReportProgress(percentage += 5); 

后来,我更新更改为单百分比,而写入数据的多块闪存:

// update progress bar in backgroundWorker thread 
    if (blockCount % 10 == 0) 
    { 
     bw.ReportProgress(percentage++); 
    } 

我想感谢大家为他们的输入,我希望这个答案可以节省一些人编写额外的一千行代码。我希望能够收到有关此答案的反馈,并且我仍然对其他更好的解决方案感兴趣。

4

如果您正在寻找真正的进展,那么您的更新程序将需要提高进度。您可以引发事件出来updater,并从内部worker_DoWork订阅它们,并使用ReportProgress封送它回到了进度报告UI线程:

void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    updater.Progress += updater_Progress; 
    try { 
     updater.updater(); 
    } finally { 
     updater.Progress -= updater_Progress; 
    } 
} 
void updater_Progress(object sender, ProgressEvents evt) { 
    worker.ReportProgress(evt.Percent); 
} 

当然,这需要你在创建进度事件您Updater类,并调用该事件,因为您的updater方法起作用。

BackgroundWorker的做了两件事对你:

  • 让您在后台线程中运行任务,让你的UI线程保持响应
  • 让您轻松地从后台线程到UI线程元帅的进展,而不必使用Form.Invoke

DoWork事件在后台线程中触发。该事件处理程序中的所有内容都按正常代码的顺序发生,而您的UI线程仍然继续运行。如果你要假的进步,你会做与从UI线程的计时器回调更新进度,而BackgroundWorker的在后台运行,你的更新代码

+0

我喜欢这个答案,但是我很难实现事件和处理程序。 updater是FWudpater的一个实例。 请参阅上面原始问题中的编辑。谢谢! – Gordon

+0

@戈登,你应该发布一个新问题,不要编辑这个问题。将可能会降落在这里的其他人的答案和问题保存在一起。 – Tim

-1

你可以解决它像这样

BackgroundWorker worker; 

public void Init() 
{ 
    worker = new BackgroundWorker(); 
    worker.DoWork += Worker_DoWork; 
    worker.ProgressChanged += Worker_ProgressChanged; 
    worker.WorkerReportsProgress = true; // This is important 
    worker.RunWorkerAsync(); 
} 

private void Worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // Do your update progress here... 

    for (int i = 0; i <= 100; i++) // This simulates the update process 
    { 
     System.Threading.Thread.Sleep(100); 
     worker.ReportProgress(i); // Report progress from the background worker like this 
    } 
} 

private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    // Update the progress bar or other ui elements here... 
    // Use the e.ProgressPercentage 
} 

这是绝对可以长时间运行后台工作。我从来没有遇到任何问题,即使有一个在任何时间运行。

相关问题