2015-08-30 2 views
0

Я пытаюсь прочитать данные из моего USB-буфера. Однако, когда я читаю данные из буфера, я должен выполнить некоторую операцию над этими данными, и это требует времени. В то же время внешнее устройство наблюдает, что буфер заполнен и прекращает записывать данные. Мне нужно преодолеть эту ситуацию. Перерабатывающий включает в себя чтение массива и некоторые операции UI, так что я, хотя я мог бы поставить всю операцию чтения данных в фоновом поток и читать данные, когда фоновый поток завершил операциюC# background thread worker

BackgroundWorker bw = new BackgroundWorker(); 

     // this allows our worker to report progress during work 
     bw.WorkerReportsProgress = true; 

     // what to do in the background thread 
     bw.DoWork += new DoWorkEventHandler(
     delegate(object o, DoWorkEventArgs args) 
     { 
      BackgroundWorker b = o as BackgroundWorker; 

      // do some simple processing for 10 seconds 
      for (int i = 1; i <= 10; i++) 
      { 
       // report the progress in percent 
       b.ReportProgress(i * 10); 
       Thread.Sleep(1000); 
      } 
      //I have to keep reading from the buffer here 


     }); 

     // what to do when progress changed (update the progress bar for example) 
     bw.ProgressChanged += new ProgressChangedEventHandler(
     delegate(object o, ProgressChangedEventArgs args) 
     { 
      label1.Text = string.Format("{0}% Completed", args.ProgressPercentage); 
     }); 

     // what to do when worker completes its task (notify the user) 
     bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
     delegate(object o, RunWorkerCompletedEventArgs args) 
     { 
      label1.Text = "Finished!"; 
      //I have to use the data from the buffer here 
     }); 

     bw.RunWorkerAsync(); 

Но даже при таком подходе Я до сих пор не читаю буфер непрерывно, так как только после завершения операции над пользовательским интерфейсом я могу снова вызвать фонового рабочего. Есть ли способ постоянно читать буфер (например, в большой массив 2d) и продолжать уведомлять меня, когда каждый 1d массив буфера заполнен? Основная идея заключается в том, что задачу у работника не следует останавливать, однако мне все же нужно получить данные из рабочей задачи (знайте, что она завершена). Какой был бы лучший способ достичь этого?

+0

Добавить код о чтении буфера. –

+0

Я использую пользовательскую функцию для фактического чтения буфера. Это синхронный вызов и возвращается после того, как необходимое количество байтов было прочитано в массиве. –

+0

Ваш вопрос не о фоновом работнике. Операция рабочего стола проста, вы должны задавать вопрос о непрерывном чтении из буфера и сообщать о ходе чтения, поэтому нужен некоторый код чтения буфера. –

ответ

1

Может быть, в вашем случае, используя следующий класс будет пригодиться:

public class BackgroundTimer : BackgroundWorker 
    { 
     private ManualResetEvent intervalManualReset; 
     private enum ProcessStatus { Created, Running, JobCompleted, ExceptionOccured }; 
     private ProcessStatus processStatus = new ProcessStatus(); 

     public int Interval { get; set; } 
     public BackgroundTimer() 
     { 
      this.processStatus = ProcessStatus.Created; 
      this.WorkerSupportsCancellation = true; 
      this.Interval = 1000; 
     } 

     protected override void OnRunWorkerCompleted(RunWorkerCompletedEventArgs e) 
     { 
      base.OnRunWorkerCompleted(e); 
      if (processStatus == ProcessStatus.ExceptionOccured) 
       // Log : Process stopped; 
       processStatus = ProcessStatus.JobCompleted; 
     } 
     protected override void OnDoWork(DoWorkEventArgs e) 
     { 
      while (!this.CancellationPending) 
      { 
       try 
       { 
        base.OnDoWork(e); 
        this.Sleep(); 
       } 
       catch (Exception exception) 
       { 
        //Log excepption; 
        this.processStatus = ProcessStatus.ExceptionOccured; 
        this.Stop(); 
       } 
      } 
      if (e != null) 
       e.Cancel = true; 
     } 

     public void Start() 
     { 
      this.processStatus = ProcessStatus.Running; 
      if (this.IsBusy) 
       return; 

      this.intervalManualReset = new ManualResetEvent(false); 
      this.RunWorkerAsync(); 
     } 
     public void Stop() 
     { 
      this.CancelAsync(); 
      this.WakeUp(); 
      this.Dispose(true); 
     } 
     public void WakeUp() 
     { 
      if (this.intervalManualReset != null) 
       this.intervalManualReset.Set(); 
     } 
     private void Sleep() 
     { 
      if (this.intervalManualReset != null) 
      { 
       this.intervalManualReset.Reset(); 
       this.intervalManualReset.WaitOne(this.Interval); 
      } 
     } 
     public void Activate() 
     { 
      if (!this.IsBusy) 
       // Log : Process activated. 
       this.Start(); 
     } 
    } 

EDIT: Использование:

 private void InitializeThread() 
     { 
      var timer = new BackgroundTimer(); 
      timer.Interval = 1000; // sleep 1 second between each iteration. 
      timer.DoWork += timer_DoWork; 
      timer.Start(); 
     } 

     void timer_DoWork(object sender, DoWorkEventArgs e) 
     { 
      // your desired operation. 
     } 

Я надеюсь, что это помогает.

+0

После выполнения этой работы я не должен спать, но мне все еще нужен доступ к данным. Мне также нужно знать, что это закончено. Как мне это сделать? –

+0

вы можете проверить свойство IsBusy, чтобы проверить, работает он или нет. Но он обрабатывает чтение из буфера на регулярной основе и, возможно, вы можете использовать память, в которую записывает работник фона, и ваш другой поток читает. –

+0

Не могли бы вы добавить фрагмент относительно того, как это делается? –