사용자 클래스에서 발생하는 이벤트를 통해 GUI 요소를 업데이트하면서이 문제가 발생했지만 다음과 같이 처리 할 수있었습니다 :다른 스레드가 스레드를 소유하고 있기 때문에 스레드간에 객체를 전달하면 예외가 발생합니다.
MyTextBlock.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
(Action)(() => { LoggingTextBlock.Text += Message += "\r\n"; }));
이 문제는 UI 스레드에 고유하다고 생각했지만 분명히 모든 스레드에 적용됩니다. 불행히도 내 사용자 정의 클래스에는 UIElements처럼 호출 할 .Dispatcher() 루틴이 없습니다. 그렇다면 어떻게 객체를 다른 쓰레드에 전달하고 쓰레드를 사용할 수있게할까요?
예를 들어 기본 청취자 클래스는 기본적으로 일부 데이터를 찾고, 이벤트를 발생시키고, 해당 데이터를 전달하는 것입니다. ,
// Just the class for carrying the job data.
public class JobData
{
// NOTE: I don't no have trouble accessing these properties from a
// different thread
public string SomeProperty1 { get; set; }
public string SomeProperty2 { get; set; }
public string SomeProperty3 { get; set; }
// ...
// more properties
// ...
// This a .NET object of type System.Printing.PrintSystemJobInfo. This
// is the guy that gives me trouble. Later on, I can't access members
// of Job without getting the "The calling thread cannot access this
// object because a different thread owns it" error.
PrintSystemJobInfo m_Job = null;
public PrintSystemJobInfo Job
{
get
{
if (m_Job == null)
{ throw new ArgumentNullException(); }
return m_Job;
}
set { m_Job = value; }
}
}
다음은 스레드에서 실행되는 클래스의 세그먼트 데이터를 수집하고,에 떨어져 그 데이터를 전달하는 이벤트를 발생 : 다음은 내가 전달하고자하는 데이터 클래스의 세그먼트입니다 듣는 사람.
// Thread who monitors looking for data to package into JobData and send
// to any listeners.
public class JobMonitor
{
public delegate void NewJobEvent(JobData jobStuff);
public event NewJobEvent NewJob;
// Call this when you have some job data and need to notify listeners
private void OnNewJob(object newJobData)
{
JobData newJobData = (JobData)newJobData;
if (NewJob != null)
{
NewJob(newJobData);
}
}
private void WorkerRoutine()
{
while(true)
{
// Wait for data
// ...
// ...
// when data is found
JobData myJobData = new JobData();
myJobData.SomeProperty1 = "some data";
myJobData.SomeProperty2 = "some data";
int jobID = GetCurrentJobID();
string printerName = GetCurrentPrinterName();
// .NET class System.Printing.PrintQueue
PrintQueue printQueue = new PrintQueue(new PrintServer(), printerName);
PrintSystemJobInfo jobInfo = null;
jobInfo = printQueue.GetJob(jobID);
// This is the guy in my JobData class that I'll have trouble accessing
// later on.
myJobData.Job = jobInfo;
// Time to fire off the event
OnNewJob(myJobData);
}
}
}
다음은 JobMonitor 클래스를 인스턴스화하고 이벤트를 캡처하는 클래스의 세그먼트입니다. JobMonitor의 속성 중 하나에 액세스하는 데 문제가 있습니다.
// This class signs up to recieve and process events from the JobMonitor class.
public class JobProcessor
{
// this is the method that handles the incoming job events. This is where
// i have trouble.
private void NewJobEventHandler(JobData newJob)
{
string temp = newJob.SomeProperty1; // this works fine
bool bTemp = newJob.Job.IsPaused; // this throws an exception "The
// calling read cannot access this
// object because a different thread
// owns it"
}
private JobMonitor m_monitor = null;
public JobProcessor()
{
m_monitor = new JobMonitor();
//attaches a method to handle incoming job events.
m_monitor.NewJob += new JobMonitor.NewJobEvent(NewJobEventHandler);
m_monitor.Start();
}
}
는 그래서 JobProcessor.NewJobEventHandler() 메소드는 내가 예외를 받고 있어요 여기서 "다른 스레드가 그것을 소유하고 있기 때문에 호출 스레드가이 개체에 액세스 할 수 없습니다"입니다. 이 속성과 속성 및 메서드에 액세스 할 수 있어야합니다. 필요한 것을 액세스하려면 무엇을해야합니까?
글쎄, 나는 다른 제안이 있는지를보기 위해 조금 기다렸다. "SyncronizationContext"방식은 나에게 열매를 맺지 못했습니다. 나는 개념을 조금 잃어 버렸기 때문에 잘못했을 가능성이 큽니다. 다행스럽게도 PrintSystemJobInfo 객체를 검색하는 것은 쉽고 내 대상 스레드가 이동하여이 객체를 독자적으로 가져올 수있는 충분한 정보가 있습니다. 이상적으로는이 작업을 수행 할 필요가 없으며 대상 스레드는이 정보를 가져 오는 방법을 알 필요가 없습니다. 오 잘, 저를위한 타협의 그것의 큰 아닙니다 그것의 관점에서 두십시오. – Ultratrunks