Можно загрузить GNU Emacs NT от здесь прямой. Это хорошо работает в окнах, удостоверьтесь, что Вы создаете ярлык на файл runemacs.exe, а не файл emacs.exe, таким образом, это не показывает командную строку перед открытием!
XEmacs менее стабилен, чем GNU Emacs, и много расширений конкретно записано для GNU. Я рекомендовал бы GNU> X.
, можно поместить .emacs файл в корень диска, на котором это установлено. Не уверенный, можно ли добавить его в другом месте также...
Вам следует сделать наоборот. Запустите длительный процесс в фоновом потоке и оставьте поток пользовательского интерфейса свободным, чтобы он мог реагировать на действия пользователя.
Если вы хотите заблокировать какие-либо действия пользователя во время обработки, у вас есть несколько опций, включая модальные диалоги. Как только фоновый поток завершит обработку, вы можете сообщить основному потоку о результате
Код, выполняющийся в событиях привязки данных, должен быть отделен от пользовательского интерфейса, возможно, с использованием какого-либо объекта передачи данных.
Затем вы можете запустить операцию запроса в отдельном потоке или BackgroundWorker
, и оставьте поток пользовательского интерфейса, как он был.
Изменить: действительно быстрый способ исправить это - заставить события запускаться в собственном делегате с помощью InvokeRequired
и .Invoke
. Это даст контексту пользовательского интерфейса методов. Мой коллега делает это так, будто это выходит из моды, и меня это безмерно раздражает, потому что редко бывает хорошей идеей делать это таким образом ... но если вам нужно быстрое решение, это сработает. (Я не на работе, поэтому у меня нет сэмпла; я попробую что-нибудь придумать.)
Редактировать 2: Я не уверен, что вы ' повторный запрос возможно. Я сделал образец приложения, которое создало модальный диалог в другом потоке, и в итоге оно оказалось немодальным. Можно ли вместо использования модального диалогового окна использовать какой-либо другой элемент управления или набор элементов управления для индикации изменения хода выполнения, скорее всего, непосредственно в той же форме?
using( var frmDialog = new MyPleasWaitDialog() ) {
// data loading is started after the form is shown
frmDialog.Load += (_sender, _e) {
// load data in separate thread
ThreadPool.QueueWorkItem( (_state)=> {
myAdapter.Fill( myDataSet );
// refresh UI components in correct (UI) thread
frmDialog.Invoke( (Action)myDataControl.Refresh );
// close dialog
frmDialog.Invoke( (Action)frmDialog.Close() );
}
}
// shows dialog
frmDialog.ShowDialog( this );
}
Вот пример использования BackgroundWorker для загрузки данных и запуска удобной формы для отображения «Загрузка записей» или чего-то подобного ...
public void Run()
{
bgWorkrFillDS = new BackgroundWorker();
bgWorkrFillDS.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorkrFillDS_RunWorkerCompleted);
bgWorkrFillDS.DoWork += new DoWorkEventHandler(bgWorkrFillDS_DoWork);
bgWorkrFillDS.RunWorkerAsync();
}
void bgWorkrFillDS_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bgWrkrFillDS = (BackgroundWorker)sender as BackgroundWorker;
if (bgWrkrFillDS != null)
{
// Load up the form that shows a 'Loading....'
// Here we fill in the DS
// someDataSetAdapter.Fill(myDataSet);
}
}
void bgWorkrFillDS_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Hide or unload the form when the work is done
}
Надеюсь, это поможет ... Береги себя, Том.
Я решил эту проблему, создав новый DataSet, загрузившись в фоновом режиме, а затем вызвав DataSet.Merge
в потоке пользовательского интерфейса. Спасибо всем за ваш совет, который привел к этому решению.
В качестве дополнительного бонуса это работает намного быстрее, чем раньше (вызов Fill
в фоновом режиме, который работал только без открытых сеток). Кто-нибудь знает почему?