2017-01-09 4 views
0

Есть ли способ заставить функцию ждать определенного внешнего значения перед возвратом результата? Вот очень рудиментарный пример:Ожидание значения до результата функции сохранения

Function DoSomething() As boolean 
'' ... do something external that takes time and sets a Registry value when done 
'' ... 

    Dim isTaskDone as Boolean 

    Do Until isTaskDone = True 
    isTaskDone = Registry.GetValue("ExternalValuePath", "valName", 0) 
    Loop 

    Return var 
End Function 

Это на самом деле работает для моих потребностей, но мне было интересно, может быть, есть более элегантный способ достижения этой цели? Также я не уверен, что это решение в порядке, чтобы оставить его таким (используя Until, чтобы эффективно остановить функцию).
Приносим извинения за довольно расплывчатый вопрос.

Обновление:
Я предполагаю, что я ищу какое-то простое решение с одним вызовом, где я могу назвать одну функцию, она делает все, что мне нужно, и возвращает результат только тогда, когда все будет сделано. Поэтому я знаю, что безопасно продолжать.
Я также пробовал это с Timers, но я не думаю, что можно использовать все в одноразовом решении при использовании Timers.

+0

Зачем вам нужно подождать? Это [этот метод «Registry.GetValue»] (https://msdn.microsoft.com/en-us/library/microsoft.win32.registry.getvalue (v = vs.110) .aspx)? Если это так, он не должен компилироваться, потому что он исключает три параметра. –

+0

Эта функция должна отправлять команды внешним приложениям и ждать их завершения и сохранения некоторых данных на диск. Мне нужно использовать данные, сохраненные этими внешними приложениями. Мне нужно подождать, чтобы получить последнюю версию сохраненных данных. –

+0

Извините. Я упрощал улучшать читаемость моего примера. Да, это общий метод чтения реестра. –

ответ

2

Лучшим подходом было бы создание наблюдателя реестра с использованием WMI. Обратитесь к link, его в C# не должно быть проблемой для конвертации в VB.Net

+0

Спасибо за ответ. Я займусь этим. –

1

В вашем методе используется цикл ожидания занятости, который заблокирует ваш пользовательский интерфейс (и расторгнет циклы процессора). Возможно, для этого можно использовать BackgroundWorker, но вы, вероятно, также можете выполнить его с помощью Timer. Не очень элегантный, возможно, но это не заморозит ваш интерфейс.

Поэтому, вместо того чтобы сделать его функцией, Sub будет делать. Затем добавьте Timer по умолчанию Interval из 100. В вашем DoSomething Sub, Enable таймер. И ваш код таймера будет примерно таким:

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick 

    If Registry.GetValue("ExternalValuePath", "valName", 0) Then 
     Timer1.Enabled = False 
     'do whatever needs to be done next 
    End If 

End Sub 
+0

Благодарим за ответ! Дело в том, что я уже пробовал делать это с помощью «Таймеров». И это сработало. То, что мне не нравилось в «Таймерах», заключается в том, что «tick» является отдельным Sub из Sub, где я запускаю «Timer». Это невозможно сделать с помощью таймеров и содержать все в одной суб/функции, не так ли? То, что я ищу, - это что-то вроде однофункционального решения: я вызываю функцию, и она делает все, что мне нужно (отправляет данные в другие системные приложения) и возвращает результат только тогда, когда все сделано, поэтому я знаю, что безопасно продолжать , –

+0

@ EdgarsMiškins Я так не считаю, не вызывая проблем с UI или CPU. Даже с другим ответом ответил Мукуль. Всякий раз, когда у вас есть асинхронная связь, вам либо приходится сидеть там в цикле, что не очень хорошо, или делать какой-то опрос (таймер), что лучше, или какое-то событие обратного вызова, которое обычно является лучшим путем. Его ответ был бы ближе к последнему. – topshot

Смежные вопросы