Trong ứng dụng dịch vụ Windows của tôi, tôi đang sử dụng bộ hẹn giờ rất nhiều. Tôi chỉ sử dụng System.Timers. Tôi chưa bao giờ trải qua vấn đề này trước đây, nhưng đột nhiên tôi nhận được ngoại lệ này:.NET 3.5 C# Lỗi với System.Timer System.ObjectDisposedException: Không thể truy cập đối tượng được xử lý
System.ObjectDisposedException: Cannot access a disposed object.
at System.Threading.TimerBase.ChangeTimer(UInt32 dueTime, UInt32 period)
at System.Threading.Timer.Change(Int32 dueTime, Int32 period)
at System.Timers.Timer.UpdateTimer()
at System.Timers.Timer.set_Interval(Double value)
at MyApp.MySpace.MySpace2.MyClassWithTimer.MethodChangeTimerInterval()
Trong phương pháp của tôi, tôi đang dừng bộ đếm thời gian, và thay đổi khoảng thời gian hẹn giờ. Đó là nơi tôi có ngoại lệ.
Tôi đã đọc nội dung nào đó về lỗi này nhưng vẫn còn dễ bị lỗi này ngay cả trong .NET 3.5 không?
Làm cách nào để khắc phục sự cố? Tôi có nên gia hạn đối tượng bộ đếm thời gian sau khi dừng và đặt khoảng thời gian cho một đối tượng mới không? Tôi đang sử dụng GC.KeepAlive (dataTimer);
Edit: Tôi tìm thấy một số câu hỏi khác về vấn đề này:
* Tôi tìm thấy một liên kết http://www.kbalertz.com/kb_842793.aspx Về cơ bản ngay sau khi bạn dừng lại một bộ đếm thời gian, nội System.Threading.Timer trở nên có sẵn cho Bộ sưu tập rác, đôi khi gây ra sự kiện trôi qua không xảy ra, hoặc đôi khi gây ra ngoại lệ tham chiếu được xử lý. Mặc dù không được mô tả trong bài viết, giải pháp của tôi là để tạo bộ hẹn giờ mới mỗi khi bộ hẹn giờ được dừng lại và thêm lại các sự kiện đã trôi qua. Không hiệu quả nhưng dễ dàng, và không phải là một vấn đề xử lý-khôn ngoan với tôi. Điều này đã giải quyết được hoàn toàn vấn đề của tôi. Chúc mừng cho tất cả những ai trả lời. *
Nhưng tôi bối rối là tại sao lỗi vẫn còn đó, và tôi cần phải chắc chắn rằng lại thêm bộ đếm thời gian là một ý tưởng tốt ...
Mã mà gây ra lỗi:
private void StartAsyncResponseTimer()
{
switch (_lastRequestType)
{
case 1:
asyncResponseTimer.Interval = 1000;
break;
case 2:
asyncResponseTimer.Interval = 2000;
break;
case 3:
asyncResponseTimer.Interval = 3000;
break;
default:
asyncResponseTimer.Interval = 10000;
break;
}
asyncResponseTimer.Start();
}
Chức năng được gọi là từ sự kiện SerialPortDataReceived:
private void SerialPortDataReceived(object sender, EventArgs e)
{
StartAsyncResponseTimer();
}
hẹn giờ đã được ngừng lại trước khi gọi thay đổi khoảng thời gian.
Timer là lĩnh vực riêng của lớp học của tôi:
private Timer asyncResponseTimer = new Timer();
EDIT: Ứng dụng này đã được chạy trong nhiều tháng liên tiếp và đây là lần đầu tiên tôi nhận được ngoại lệ này!
mô hình xử lý của tôi:
public class SerialPortCommunication{
...
private void SerialPortDataReceived(object sender, EventArgs e)
{
ReadResponse();
StartAsyncResponseTimer();
}
//used to determine if is recieving response over
private void StartAsyncResponseTimer()
{
switch (_lastRequestType)
{
case 1:
asyncResponseTimer.Interval = 1000;
break;
case 2:
asyncResponseTimer.Interval = 2000;
break;
case 3:
asyncResponseTimer.Interval = 3000;
break;
default:
asyncResponseTimer.Interval = 10000;
break;
}
asyncResponseTimer.Start();
}
public virtual void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!this._disposed)
{
if (disposing)
{
// Dispose managed resources.
}
// Dispose unmanaged resources.
_disposed = true;
Stop();
}
}
~SomeClass()
{
Dispose(false);
}
#endregion
public void Stop()
{
_asyncResponseTimer.Stop();
serialPortManager.ClosePort();
}
}
Hãy cung cấp cho chúng tôi mã của bạn cũng như thông báo lỗi. Đoán của tôi là bạn đang sử dụng khối "đang sử dụng" tự động loại bỏ thứ gì đó khi kết thúc khi bạn không nên như vậy. Chúng tôi sẽ xem xét mã của bạn và cố gắng cho bạn biết. – Chris
Đối với những gì nó có giá trị kỹ thuật của tôi khi sử dụng bộ đếm thời gian là để giữ một tham chiếu đến họ xung quanh một nơi nào đó (ví dụ như một lĩnh vực tư nhân hoặc bộ sưu tập của bộ đếm thời gian) để tôi biết vẫn còn có tài liệu tham khảo. theo cách đó tôi biết họ sẽ không bị GC trước khi tôi muốn. Mặc dù bạn làm sau đó tất nhiên phải chắc chắn rằng bạn loại bỏ tham chiếu đó khi bạn đang thực hiện với đối tượng bộ đếm thời gian. – Chris
Tôi có hẹn giờ được tham chiếu là thành viên riêng tư của lớp học. – Simon