Điều tôi đang làm là tạo một đối tượng (A) giữ một tham chiếu đến đối tượng khác (B). Phần giao diện người dùng của mã của tôi chứa các đối tượng đó (A) trong một BindingList được sử dụng làm nguồn dữ liệu cho chế độ xem lưới DevExpress. Bộ điều khiển gửi các đối tượng mới được tạo (A) tới giao diện người dùng thông qua một sự kiện. Bộ điều khiển cũng có một luồng cập nhật đối tượng được tham chiếu (B). Các ngoại lệ ném đến từ DevExpress GridView và đọc "Cross thread hoạt động phát hiện. Để ngăn chặn ngoại lệ này, thiết lập DevExpress.Data.CurrencyDataController.DisableThreadingProblemsDetection = true".Sử dụng đối tượng được tham chiếu qua các chủ đề
Bây giờ tôi không muốn chặn ngoại lệ này vì mã cuối cùng sẽ kết thúc trong một ứng dụng quan trọng.
Vậy làm cách nào để cập nhật đối tượng tham chiếu trên các chuỗi mà không gây ra sự cố? Đây là mã từ ứng dụng Kiểm tra của tôi. Về cơ bản nó sẽ giống nhau trong chương trình thực tế.
CẬP NHẬT Các lỗi trong giao diện người dùng đã được cố định bởi câu trả lời từ Nicholas Butler nhưng bây giờ ngoại trừ đã chuyển sang class Employee. Tôi đã cập nhật mã để phản ánh các thay đổi.
Đây là mã của tôi
* UI *
public partial class Form1 : Form
{
private BindingList<IEmployee> empList;
EmployeeController controller;
private delegate void AddEmployeInvoke(IEmployee employee);
public Form1()
{
controller = new EmployeeController();
controller.onNewEmployee += new EmployeeController.NewEmployee(controller_onNewEmployee);
empList = new BindingList<IEmployee>();
InitializeComponent();
}
void controller_onNewEmployee(IEmployee emp)
{
AddEmployee(emp);
}
private void AddEmployee(IEmployee empl)
{
if (InvokeRequired)
{
this.Invoke(new AddEmployeInvoke(AddEmployee), new Object[] {empl});
}
else
{
empList.Add(empl);
}
}
private void Form1_Load(object sender, EventArgs e)
{
this.gridControl1.DataSource = empList;
this.gridControl1.RefreshDataSource();
controller.Start();
}
}
Bộ điều khiển:
class EmployeeController
{
List<IEmployee> emps;
Task empUpdater;
CancellationToken cancelToken;
CancellationTokenSource tokenSource;
Pay payScale1;
Pay payScale2;
public EmployeeController()
{
payScale1 = new Pay(12.00, 10.00);
payScale2 = new Pay(14.00, 11.00);
emps = new List<IEmployee>();
}
public void Start()
{
empUpdater = new Task(AddEmployee, cancelToken);
tokenSource = new CancellationTokenSource();
cancelToken = tokenSource.Token;
empUpdater.Start();
}
public bool Stop()
{
tokenSource.Cancel();
while (!empUpdater.IsCompleted)
{ }
return true;
}
private void AddEmployee()
{
IEmployee emp = new Employee("steve", ref payScale1);
ThrowEmployeeEvent(emp);
emps.Add(emp);
emp = new Employee("bob", ref payScale2);
ThrowEmployeeEvent(emp);
emps.Add(emp);
int x = 0;
while (!cancelToken.IsCancellationRequested)
{
emp = new Employee("Emp" + x, ref payScale1);
ThrowEmployeeEvent(emp);
x++;
emp = new Employee("Emp" + x, ref payScale2);
ThrowEmployeeEvent(emp);
Thread.Sleep(1000);
payScale2.UpdatePay(10.0);
payScale1.UpdatePay(11.0);
Thread.Sleep(5000);
}
}
private void ThrowEmployeeEvent(IEmployee emp)
{
if (onNewEmployee != null)
onNewEmployee(emp);
}
public delegate void NewEmployee(IEmployee emp);
public event NewEmployee onNewEmployee;
}
nhân viên Class: (Exception ném vào lớp này)
class Employee : IEmployee
{
private string _name;
private double _salary;
private Pay _myPay;
public string Name
{
get { return _name; }
set { _name = value;
//if (PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
public double Salary
{
get { return _salary; }
}
int x = 1;
public Employee(string name, ref Pay pay)
{
_myPay = pay;
_myPay.PropertyChanged += new PropertyChangedEventHandler(_myPay_PropertyChanged);
_salary = _myPay.Salary;
Name = name;
}
void _myPay_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Salary")
{
_salary = _myPay.Salary;
if (this.PropertyChanged != null)
// exception thrown on the line below
this.PropertyChanged(this, new PropertyChangedEventArgs("Salary"));
}
}
public void ChangeName()
{
Name = "Me " + x;
x++;
}
public event PropertyChangedEventHandler PropertyChanged;
}
nhân viên Interface:
interface IEmployee : INotifyPropertyChanged
{
string Name { get; set; }
double Salary { get;}
}
Pay Class:
class Pay : INotifyPropertyChanged
{
private double _salary;
private double _bonus;
public double Salary { get { return _salary; } set { _salary = value; if(PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs("Salary"));} }
public double Bonus { get { return _bonus; } set { _bonus = value; if (PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs("Bonus")); } }
public Pay(double salary, double bonus)
{
Salary = salary;
Bonus = bonus;
}
public void UpdatePay(double salary)
{
Salary += salary;
if (onChange != null)
this.onChange();
}
public void UpdatePay(double salary, double bonus)
{
Salary += salary;
Bonus += bonus;
if (onChange != null)
this.onChange();
}
public delegate void Change();
public event Change onChange;
public event PropertyChangedEventHandler PropertyChanged;
}
Tôi đánh giá rất cao sự giúp đỡ nào.
Ahh mà làm việc nhưng bây giờ trong class Employee của tôi ở phương pháp "_myPay_PropertyChanged()" this.PropertyChanged (this, PropertyChangedEventArgs mới ("Mức lương")); đang ném cùng một ngoại lệ. Tôi cũng cần phải gọi một cuộc gọi về điều đó? – Stephen
Có - Tôi đã cập nhật câu trả lời của mình. –
Hoặc bạn có thể thực hiện các sự kiện dựa trên mô hình async trong EmployeeController của bạn và bạn sẽ không phải làm bất kỳ điều này như EmployeeController sẽ chịu trách nhiệm cho việc thực hiện các cuộc gọi trên thread righe. Mất thêm một chút thời gian để hiểu, nhưng một giải pháp gọn gàng hơn nhiều. –