Я, вероятно, не использовал бы отдельный процесс для открытия файла. Вместо этого я, вероятно, использовал бы фоновый поток (если бы я думал, что операция собиралась занять много времени и возможный блок поток UI).
private delegate void FileOpenDelegate(string filename);
public void OpenFile(string filename)
{
FileOpenDelegate fileOpenDelegate = OpenFileAsync;
AsyncCallback callback = AsyncCompleteMethod;
fileOpenDelegate.BeginInvoke(filename, callback, state);
}
private void OpenFileAsync(string filename)
{
// file opening code here, and then do whatever with the file
}
, Конечно, это не хороший рабочий пример (он ничего не возвращает), и я не показал, как UI обновляется (необходимо использовать BeginInvoke на уровне UI, потому что фоновый поток не может обновить поток UI). Но этот подход обычно в том состоит, как я иду об обработке асинхронных операций в .NET.
Как уже говорили другие, для обработки Control + D , обрабатывать "конец файла".
Control + D - это часть связи между пользователем и псевдо-файлом, который вы видите как стандартный ввод. Это не означает конкретно «конец файла», но в более общем плане «очистить введенные мной данные». Сброс означает, что любой вызов read ()
на stdin в вашей программе возвращается с длиной ввода, введенной с момента последнего сброса. Если строка не пуста, ввод становится доступным для вашей программы, хотя пользователь еще не набрал «return». Если строка пуста, то read ()
возвращает ноль, и это интерпретируется как «конец файла».
Таким образом, при использовании Control + D , чтобы завершить программу, он работает только в начале строки или если вы сделаете это дважды (первый раз для очистки, второй раз для read ()
, чтобы вернуть ноль).
Попробуйте:
$ cat
foo
(type Control-D once)
foofoo (read has returned "foo")
(type Control-D again)
$
Ctrl + D не является сигналом, это EOF (конец файла). Он закрывает канал стандартного ввода. Если чтение (STDIN) возвращает 0, это означает, что stdin закрыт, что означает, что Ctrl + D был нажат (при условии, что на другом конце канала есть клавиатура).
Минималистичный пример:
#include <unistd.h>
#include <stdio.h>
#include <termios.h>
#include <signal.h>
void sig_hnd(int sig){ (void)sig; printf("(VINTR)"); }
int main(){
setvbuf(stdout,NULL,_IONBF,0);
struct termios old_termios, new_termios;
tcgetattr(0,&old_termios);
signal( SIGINT, sig_hnd );
new_termios = old_termios;
new_termios.c_cc[VEOF] = 3; // ^C
new_termios.c_cc[VINTR] = 4; // ^D
tcsetattr(0,TCSANOW,&new_termios);
char line[256]; int len;
do{
len=read(0,line,256); line[len]='\0';
if( len <0 ) printf("(len: %i)",len);
if( len==0 ) printf("(VEOF)");
if( len >0 ){
if( line[len-1] == 10 ) printf("(line:'%.*s')\n",len-1,line);
if( line[len-1] != 10 ) printf("(partial line:'%s')",line);
}
}while( line[0] != 'q' );
tcsetattr(0,TCSANOW,&old_termios);
}
Программа меняет символ VEOF (с Ctrl-D) на Ctrl-C и символ VINTR (с Ctrl-C) на Ctrl-D. Если Вы нажмете Ctrl-D, то драйвер терминала отправит SIGINT обработчику сигнала программы.
Примечание: нажатие VINTR сотрет входной буфер терминала, поэтому вы не сможете прочитать символы, введенные в строке перед клавишей VINTR нажата.
Насколько мне известно, Ctrl + D переводится системой в конец стандартного ввода, поэтому ваше приложение не получит никакого сигнала.
Я думаю, что единственный способ перехватить Ctrl + D - это работать напрямую с системным api (например, доступ к tty)
Вы можете использовать poll () и следить за POLLHUP на fd # 1, потому что слой TTY преобразует ^ D в EOF.