2013-04-28 71 views
2

某些代碼:C#BackgroundWorker的和跟蹤條

功能用於鎖定的位圖數據:

public static BitmapData LockData(Bitmap bitmap) 
    { 
     Rectangle bitmapRect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); 
     BitmapData bitmapData = bitmap.LockBits(bitmapRect, ImageLockMode.ReadWrite, bitmap.PixelFormat); 

     return bitmapData; 
    } 

功能,用於解鎖bitnapData:

public static void UnlockData(Bitmap bitmap, BitmapData bitmapData) 
    { 
     bitmap.UnlockBits(bitmapData); 
    } 

功能改變圖像亮度:

public static void Bright(int bright, BitmapData bitmapData, BackgroundWorker worker, DoWorkEventArgs e) 
    { 
     byte nPixelFormat = 0; 
     if (bitmapData.PixelFormat == PixelFormat.Format24bppRgb) nPixelFormat = 3; 
     else if (bitmapData.PixelFormat == PixelFormat.Format32bppArgb) nPixelFormat = 4; 

     int max = bitmapData.Height - 1; 
     int percent = 0; 

     unsafe 
     { 
      for (int y = 0; y < bitmapData.Height; y++) 
      { 
       byte* pBmpRow = (byte*)(bitmapData.Scan0 + y * bitmapData.Stride); 

       for (int x = 0; x < bitmapData.Width; x++) 
       { 
        if (worker.CancellationPending) 
        { 
         e.Cancel = true; 
         return; 
        } 
        int bVal = pBmpRow[nPixelFormat * x] + bright; 
        int gVal = pBmpRow[nPixelFormat * x + 1] + bright; 
        int rVal = pBmpRow[nPixelFormat * x + 2] + bright; 



        Clamp(ref bVal); 
        Clamp(ref gVal); 
        Clamp(ref rVal); 


        pBmpRow[nPixelFormat * x] = (byte)bVal; 
        pBmpRow[nPixelFormat * x + 1] = (byte)gVal; 
        pBmpRow[nPixelFormat * x + 2] = (byte)rVal; 
       } 
       //System.Threading.Thread.Sleep(5); 
       int curPercent = (y * 100)/max; 

       if (curPercent > percent) 
       { 
        percent = curPercent; 
        worker.ReportProgress(percent); 
       } 
      } 
     } 
    } 

在這個函數中,我正在檢查backgroundWorker中止和更新進度。

現在我正在使用w trackbar和numericBox來改變亮度。當trackbar或numericBox值發生更改時,backgroundWorker將啓動。問題是,當backgroundWorker很忙,我已經改變了trackbarValue,backgroundWorker應該停止並重新開始。現在在我的代碼中,它的作品按鈕。當工作人員忙碌時,價值變化會阻止工作人員,然後下一次值更改會啓動它

代碼:

private void OnNumericBoxValueChanged(object sender, EventArgs e) 
    { 


     m_trkBarBright.Value = (int)m_numericBright.Value; 

     brightValue = m_trkBarBright.Value; 
     if (backgroundWorker.IsBusy) 
     { 
      backgroundWorker.CancelAsync(); 
     } 
     else 
     { 
      backgroundWorker.RunWorkerAsync(); 
     } 


     m_btnOK.Focus(); 
    } 


    private void WorkerDoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = (BackgroundWorker)sender; 


     Colors.CopyImgData(m_orgImage, m_tempImage); 
     data = Colors.LockData(m_tempImage); 

     Colors.Bright(brightValue, data,worker, e); 

    } 

    private void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     if (e.Error != null) 
     { 
      Colors.UnlockData(m_tempImage, data); 
      MessageBox.Show(e.Error.Message); 
      progressBar1.Value = 0; 

     } 
     else if (e.Cancelled) 
     { 
      Colors.UnlockData(m_tempImage, data); 
      if(!exit) 
      m_imgBox.UpdateImage(m_tempImage); 
      MessageBox.Show("Canceled"); 
      progressBar1.Value = 0; 

     } 
     else 
     { 
      Colors.UnlockData(m_tempImage, data); 
      if (!exit) 
      m_imgBox.UpdateImage(m_tempImage); 
      progressBar1.Value = 0; 
      MessageBox.Show("Done"); 

     } 
    } 

    private void WorkerProgress(object sender, ProgressChangedEventArgs e) 
    { 
     progressBar1.Value = e.ProgressPercentage; 
    } 

任何人有任何想法如何解決這個問題?

回答

0

執行此操作的正確方法是檢查backgroundWorker.CancellationPending並從WorkerDoWork設置e.Cancel = true

CancelAsync不會停止工作器,它只是將消息發送給一個線程說:「我想停止」。

這是full sample