Для тренировки решил написать программу позволяющую редактировать txt файлы. С считыванием и редактированием файлов проблем не возникло, при запуске же метода сохранения файла столкнулся с проблемой, что во время процесса сохранения весь интерфейс программы становится недоступным, что не очень хорошо, ведь по задумке пользователь должен иметь возможность продолжить работать с файлом. Я логически пришёл к выводу, что процесс сохранения (метод отвечающий за сохранение) нужно запустить в другом потоке, но сделать это с помощью Thread не является возможным, потому что мой метод имеет возвращаемое значение (оно указывает успешно сохранился файл, или нет). И тут стал вопрос, нужно ли мне убрать возвращаемое значение метода для запуска его через Thread (чего не хотелось бы), или существует возможность его запуска во вторичном потоке с оставлением возвращаемого значения?
Вы можете запустить выполнение данного метода асинхронно используя метод BeginInvoke у делегатов, который вернёт Вам экземпляр приведённый к интерфейсу IAsyncResult. После этого на делегате вызвать метод EndInvoke передавая ему полученный ранее экземпляр класса приведённого к интерфейсу IAsyncResult. Пример:
Func<int, int, int> myDelegate = new Func<int, int, int>((a, b) => a + b );
IAsyncResult asyncResult = myDelegate.BeginInvoke(1, 2, null, null);
// Получение результата асинхронной операции.
int result = myDelegate.EndInvoke(asyncResult);
Console.WriteLine("Результат = " + result);
Кроме этого варианта, также можно получить возвращаемое значение через использование задач (Tasks) или Фабрики задач (TaskFactory):
struct Arguments
{
public int a;
public int b;
}
static int Sum(object arg)
{
int a = ((Arguments)arg).a;
int b = ((Arguments)arg).b;
Thread.Sleep(2000);
return a + b;
}
Arguments args;
args.a = 2;
args.b = 3;
Task<int> task;
// Tasks
task = new Task<int>(Sum, args);
task.Start();
// TaskFactory
TaskFactory<int> factory = new TaskFactory<int>();
task = factory.StartNew(Sum, args);
Console.WriteLine("Sum = " + task.Result);
И последний вариант, это получение возвращаемого значения с использованием ключевых слов asunc/await:
static int a = 2;
static int b = 2;
public static async Task<int> OperationAsync()
{
return await Task<int>.Factory.StartNew(() => a + b);
}
static void Main()
{
Task<int> task = OperationAsync();
task.ContinueWith(t => Console.WriteLine("Результат : {0}", t.Result));
Console.ReadKey();
}
Вы должны учитывать, что все наведённые выше способы имеют свои особенности работы, поэтому изначально знакомьтесь с ними. Для этого можете почитать Рихтера или посмотреть уроки посвящённые работе с потоками (например у ITVDN на курсе С# Proffesional)
Всем спасибо!