Если вы используете сервлеты или класс действия для создания своего списка, а затем перенаправляете его на свой JSP, вы должны иметь следующую строку в своем сервлете или классе действий.
ArrayList<Person> names = "get from somewhere";
request.setAttribute("personNames",names);
<c:foreach var="item" items="${personNames}"> ${item.title} </c:foreach>
. Сеть уже идет System.ComponentModel.BackgroundWorker
класс конкретно для справлений с работающими фоновыми задачами и связывающийся с GUI. Используйте его.
Ничего себе, я не могу верить, как может, люди не потрудились читать вопрос.
Так или иначе, это - то, что я делаю.
Удостоверяются, что Вы не совместно используете объекты между двумя потоками. Как только Ваш поток GUI прикрепляет сообщение в Очередь, поток GUI больше не владеет сообщением. Это не может содержать ссылку на сообщение, или Вы вовлечете себя в проблему.
Это не даст Вам самую лучшую производительность, но это будет достаточно хорошо для большинства приложений. И что еще более важно, это сделает его намного тяжелее, чтобы сделать ошибку.
ОБНОВЛЕНИЕ: не используйте SyncLock и Очередь. Вместо этого используйте ConcurrentQueue, который обработает любую блокировку автоматически для Вас. Вы получите лучшую производительность и, менее вероятно, сделаете ошибку.
В действительности Вы создали версию бедного человека ThreadPool. Ваш второй поток просто находится, там ничего не делая и без изрядного количества работы с Вашей стороны, Вы не можете только заставить его делать работу для Вас. Необходимо было бы передать делегатов в очередь, которую поток тогда снимает и выполняет.
Ваш лучший выбор состоит в том, чтобы сделать то, что Вы предназначили, и просто используйте.NET ThreadPool и дайте ему работу, чтобы сделать.
Я предполагаю, что некоторое событие в GUI требует некоторой продолжительной задачи запуститься, которые выполняются в фоновом режиме - существует два основных способа сделать это. Если Вы просто хотите назвать метод на различном потоке тогда, можно сделать это Звонящие Синхронные Методы Асинхронно . Я обычно делаю что-то вроде этого:
//delegate with same prototype as the method to call asynchrously
delegate void ProcessItemDelegate(object item);
//method to call asynchronously
private void ProcessItem(object item) { ... }
//method in the GUI thread
private void DoWork(object itemToProcess)
{
//create delegate to call asynchronously...
ProcessItemDelegate d = new ProcessItemDelegate(this.ProcessItem);
IAsyncResult result = d.BeginInvoke(itemToProcess,
new AsyncCallback(this.CallBackMethod),
d);
}
//method called when the async operation has completed
private void CallbackMethod(IAsyncResult ar)
{
ProcessItemDelegate d = (ProcessItemDelegate)ar.AsyncState;
//EndInvoke must be called on any delegate called asynchronously!
d.EndInvoke(ar);
}
знать при использовании этого метода, что обратный вызов выполняется на фоновом потоке, таким образом, любые обновления GUI должны быть сделаны с помощью, Вызывают.
, Кроме того, Вы могли использовать общее состояние, чтобы связаться между потоками и использовать EventWaitHandle для передачи сигналов об обновлениях общего состояния - в этом примере, метод в GUI добавляет объекты работы к очереди, чтобы быть обработанным в фоновом режиме. Рабочий поток обрабатывает объекты от очереди, когда работа становится доступной.
//shared state
private Queue workQueue;
private EventWaitHandle eventHandle;
//method running in gui thread
private void DoWork(Item itemToProcess)
{
//use a private lock object instead of lock...
lock(this.workQueue)
{
this.workQueue.Add(itemToProcess);
this.eventHandle.Set();
}
}
//method that runs on the background thread
private void QueueMonitor()
{
while(keepRunning)
{
//if the event handle is not signalled the processing thread will sleep here until it is signalled or the timeout expires
if(this.eventHandle.WaitOne(optionalTimeout))
{
lock(this.workQueue)
{
while(this.workQueue.Count > 0)
{
Item itemToProcess = this.workQueue.Dequeue();
//do something with item...
}
}
//reset wait handle - note that AutoResetEvent resets automatically
this.eventHandle.Reset();
}
}
}
Удобство Управления. От BeginInvoke () трудно отказаться. Вы не имеете к. Добавьте новый класс к своему проекту и вставьте этот код:
using System;
using System.Threading;
using System.Windows.Forms;
public partial class frmWorker : Form {
public frmWorker() {
// Start the worker thread
Thread t = new Thread(new ParameterizedThreadStart(WorkerThread));
t.IsBackground = true;
t.Start(this);
}
public void Stop() {
// Synchronous thread stop
this.Invoke(new MethodInvoker(stopWorker), null);
}
private void stopWorker() {
this.Close();
}
private static void WorkerThread(object frm) {
// Start the message loop
frmWorker f = frm as frmWorker;
f.CreateHandle();
Application.Run(f);
}
protected override void SetVisibleCore(bool value) {
// Shouldn't become visible
value = false;
base.SetVisibleCore(value);
}
}
Вот некоторый пример кода для тестирования его:
public partial class Form1 : Form {
private frmWorker mWorker;
public Form1() {
InitializeComponent();
mWorker = new frmWorker();
}
private void button1_Click(object sender, EventArgs e) {
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
mWorker.BeginInvoke(new MethodInvoker(RunThisOnThread));
}
private void RunThisOnThread() {
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
}
private void button2_Click(object sender, EventArgs e) {
mWorker.Stop();
}
}
Используйте объект синхронизации для передачи сигналов о потоке, что он должен обработать новые данные (или новое состояние GUI). Один относительно простой способ сделать это должно использовать объект-событие. Вот краткое изложение того, как это работало бы:
Поместите цикл в свой второй поток, который спит большую часть времени, но каждый [Интервал] он просыпается и проверяет совместно используемую переменную, которая говорит его, выполнить ли Ваш метод или нет, и если та общая булевская переменная имеет значение true, то он выполняет метод, который выполняет любую задачу, которую Вы пытаетесь выполнить... В том методе имейте метод, собирают данные, требуемые от другой совместно используемой переменной.
В основном потоке GUI, помещенном данные в совместно используемую переменную параметра метода, затем устанавливает булеву совместно используемую переменную "Выполнения" на истинный...
Внутренняя часть метод рабочего, не забудьте сбрасывать общий bool "выполненная" переменная ко лжи, когда Вы будете сделаны, таким образом, выигранный цикл; t выполняют тот же экземпляр много раз...
Можно использовать события или как Grauenwolf заявил - сигнал сообщения. Я обертываю каждый свой поток как одиночный элемент управления, оттуда можно реализовать любого легко. Вы могли даже сделать плохие общественные собственности человека для зеркального отражения битов.
Также Вы могли реализовать конечный автомат, и вместо передачи обменивается сообщениями, каждый поток мог контролировать друг друга