2013-04-09 31 views
5

Tôi sẽ phát điên với một mã đơn giản [WPF C#] trong đó tôi sử dụng một BackgroundWorker để tự động hóa các thao tác cơ bản. Tôi có nên thêm nội dung vào khay nhớ tạm không.BackgroundWorker và ClipBoard

Sau khi thực hiện mã này trong phương pháp của BackgroundWorker:

Clipboard.SetText (splitpermutation [i]); 

tôi nhận được một lỗi mà giải thích các chủ đề phải STA, nhưng tôi không hiểu làm thế nào để làm. mã ở đây nữa: (không phải tất cả)

private readonly BackgroundWorker worker = new BackgroundWorker(); 

private void btnAvvia_Click(object sender, RoutedEventArgs e) 
{ 
      count = lstview.Items.Count; 
      startY = Convert.ToInt32(txtY.Text); 
      startX = Convert.ToInt32(txtX.Text); 
      finalY = Convert.ToInt32(txtFinalPositionY.Text); 
      finalX = Convert.ToInt32(txtFinalPositionX.Text); 
      incremento = Convert.ToInt32(txtIncremento.Text); 
      pausa = Convert.ToInt32(txtPausa.Text); 

      worker.WorkerSupportsCancellation = true; 
      worker.RunWorkerAsync(); 

      ... 
} 

private void WorkFunction(object sender, DoWorkEventArgs e) 
{ 
    [...] 
        if (worker.CancellationPending) 
        { 
         e.Cancel = true; 
         break; 
        } 
        else 
        { 
         [...] 
         Clipboard.SetText(splitpermutation[i]); 
         [...] 
        } 
} 

Trả lời

4

Bạn có thể sắp xếp này đến thread UI để làm cho nó làm việc:

else 
{ 
    [...] 
    this.Dispatcher.BeginInvoke(new Action(() => Clipboard.SetText(splitpermutation[i]))); 
    [...] 
} 
+0

Đâu là Người điều phối? Cái gì thế này'? Tôi dường như không thể tìm thấy nó. – codemann8

+0

@ codemann8 Trong WPF, mọi phần tử giao diện người dùng đều có một Dispatcher - đây là mã phía sau –

+0

Tôi không có bất kỳ kinh nghiệm nào trong WPF, tôi đang sử dụng một dự án WinForms C# chuẩn ... Có giải pháp tương đương không? – codemann8

1

Các BackgroundWorker chạy trên hồ bơi .NET chủ đề. Chủ đề hồ bơi chủ đề chạy trong căn hộ đa luồng COM. Để sử dụng khay nhớ tạm, bạn phải đang chạy trong một căn hộ đơn luồng. Bạn có thể tạo chủ đề của riêng mình và đặt nó chạy trong STA, nhưng có lẽ tốt nhất là sử dụng Control.Invoke (hoặc BeginInvoke) để quay lại luồng giao diện người dùng (phải là chuỗi STA).

0

Ngoại lệ bạn nhận được là vì bạn đang cố gắng làm điều gì đó trên chuỗi giao diện người dùng từ bên ngoài chuỗi giao diện người dùng (BackgroundWorker, như tên ngụ ý, thực hiện điều gì đó trong nền và cần tạo một chủ đề riêng biệt).

Trong khi câu trả lời được đăng bởi Reed (nghĩa là, bằng cách sử dụng Dispatcher.BeginInvoke) là một cách để tránh ngoại lệ này, tôi tự hỏi TẠI SAO bạn đang cố gắng gửi nội dung nào đó vào khay nhớ tạm từ phương thức làm việc chính ở nơi đầu tiên ...

BackgroundWorker hiển thị các sự kiện như ProgressChanged (bạn có thể gọi định kỳ từ phương thức công việc của mình) hoặc RunWorkerCompleted (sẽ kích hoạt khi phương thức làm việc chính kết thúc).

Sử dụng Clipboard.SetText trong một trong các sự kiện này không được gây ra ngoại lệ mà bạn nhìn thấy và điều này dường như là cách thích hợp hơn để thực hiện mọi thứ trên chuỗi giao diện người dùng khi làm việc với BackgroundWorker.