Background Agent кидается красным квадратом

Omh

Lotus team
04.07.2007
2 210
1
#1
Привет!

Вот возникла проблемка, не знаю куда копнуть.

Ситуация: есть база, в ней есть background agent (который в отдельном триде запускается).
Агент там что-то процессит/генерит документы и т.д.
Я хотел после генерации доков попросить его выполнить ws.ViewRefresh, дабы показать свежесгенеренные документы.
Что бы не рефрешить ws, пока юзер работает с другими базами, в самом агенте я пытаюсь анализировать, что у меня в данный момент открыто.

Ну агент негодует адово:
то просто тупо фризиться, то кидает красный квадрат с unexpected handle, то nsd-шечку покажет.
В основном это происходит, если начинаешь лазить по документам, сохранять их и т.д.

Вся эта фигня происходит имеено в блоке определения текущей базы.
Если его закомментить, то начинает работать железно, но рефрешить лишние разы, что бесит.
ErrorHandler есть, но полчит как Исаев на допросе...

Код агента примерно такой:
Код:
AgentSleep:  
Sleep(SleepInterval)
Sleeps = Sleeps + SleepInterval

If Sleeps >= RefreshInterval Then
Sleeps = 0

If SOME_PROCESSING(Db) Then
Dim RefreshWsLocal As Boolean
RefreshWsLocal = False

Dim ws As New NotesUIWorkspace 
Dim CurrUIDb As NotesUIDatabase
Dim CurrDb As NotesDatabase

If Not RefreshWsLocal Then
Set CurrUIDb = ws.CurrentDatabase
If CurrUIDb Is Nothing Then Goto RefreshTry

Set CurrDb = CurrUIDb.Database
If CurrDb Is Nothing Then Goto RefreshTry

RefreshWsLocal = (CurrDb.Title = AgentDbTitle) 'сравнивает название текущей базы и базы, в которой крутиться агент.
End If

RefreshTry:				 
If RefreshWsLocal Then Call ws.ViewRefresh

Set CurrDb = Nothing
Set CurrUiDb = Nothing
Set Ws = Nothing

Goto AgentSleep
End If
Else
Goto AgentSleep
End If
Эни айдиас?

p.s. Сам знаю, что идея не очень хороша, но не хочется отказываться.
 

Akupaka

А че я?.. О.о
04.10.2007
3 360
1
#2
Уважаемый, агент же бекендовый, к чему удивление? ;)
А торкнуть из него другой агент, который обновит вид?
 

Omh

Lotus team
04.07.2007
2 210
1
#3
Ну, бекендовый агент спокойненько может дёргать все ws-ные методы и проперти.
Это не шедульный, а тот, у которого стоит галочка "Run in separated client thread"

Вынес объявление ws наверх из цикла, вроде перестал негодовать, ещё тестирую.
 

ToxaRat

Чёрный маг
Lotus team
06.11.2007
3 231
18
#4
Dim ws As New NotesUIWorkspace
переписывай через сесию и всё будет пахать
 

ToxaRat

Чёрный маг
Lotus team
06.11.2007
3 231
18
#7
Omh
не использовать УИ для агента вообще - но это к слову
а
вот Set CurrUIDb = ws.CurrentDatabase я вот не помню где именно я это читал но и по опыту это запрещенный метод, для определения текущей базы использовать ТОЛЬКО через Ses.CurrentDatabes
 

Omh

Lotus team
04.07.2007
2 210
1
#8
Товагищи, мне надо из бекграунд агента надо обновить текущий вид при определённых условиях.
Обновить вид можно только через ws.

Тут никакие задние объекты не годятся.
Это, кагбэ, условие задачи.

Вроде получается, кстати, я отпишусь, если выстругаю...


Понял, ща гляну через session.CurrentDatabase что даёт.
 

hosm

* so what *
18.05.2009
2 442
6
#9
есть ws.getcurrentdatabase
help сказал(а):
The GetCurrentDatabase method supersedes property CurrentDatabase due to the failure of the property when the user accesses the current database through View - GoTo (for example, on the workspace menu with the database selected).
 

Omh

Lotus team
04.07.2007
2 210
1
#10
Ради инфы: session.CurrentDatabase мне всегда возвращет базу, в которой крутиться агент.
Что логично, там session инициализирован первой сторокой и не переиницализируется.
 

Akupaka

А че я?.. О.о
04.10.2007
3 360
1
#11
вот Set CurrUIDb = ws.CurrentDatabase я вот не помню где именно я это читал но и по опыту это запрещенный метод
это даже в справке написано, о чем собсно нам сообщила цитатой OKEN ;)

Ради инфы: session.CurrentDatabase мне всегда возвращет базу, в которой крутиться агент
Не понял, чем ты хотел нас удивить? ;)

Товагищи, мне надо из бекграунд агента надо обновить текущий вид при определённых условиях.
Обновить вид можно только через ws.
А при чем тут УИшная БД?
 

nvyush

Lotus team
22.04.2009
2 317
0
#12
Как я понял, обновлять нужно только в том случае, если нужное представление является активным, т.е. с помощью ws.currentdatabase автор пытается выяснить активную в ws базу данных и, если она совпадает с бд агента, выполнить обновление. КМК сие либо нереализуемо, либо нужно курить другой бамбук.

P.S. Может покурить в сторону ws.currentview?
 

Omh

Lotus team
04.07.2007
2 210
1
#14
КМК сие либо нереализуемо, либо нужно курить другой бамбук.
P.S. Может покурить в сторону ws.currentview?
Описал правильно и сие реализуемо.
Я смотрел на currentview - начинал ещё более оголотело кидать квадратами.
Сейчас с накопленными знаниями посмотрю ещё разок.
Через вьюшку даже лучше было бы...

Не понял, чем ты хотел нас удивить? wink.gif
Своей тупостью :)
 

VladSh

начинающий
Lotus team
11.12.2009
1 262
6
#15
а вот Set CurrUIDb = ws.CurrentDatabase я вот не помню где именно я это читал но и по опыту это запрещенный метод, для определения текущей базы использовать ТОЛЬКО через Ses.CurrentDatabes
Оффтоп. Он не запрещённый. Просто был изначально написал для доступа к LND через OLE, т.е. с урезанным функционалом. Ничего страшного в нём нет, кроме того, что БД, полученная с UIDatabase ничего не возвратит в UnprocessedDocuments и т.п., что написано в хэлпе... Поэтому, чтобы разделить функционал и есть сейчас 2 метода: CurrentDatabase (для OLE или можно пользоваться ограниченным набором методов) и GetCurrentDatabase (для использования в LS). На практике использование и того и другого действительно редки, - только когда надо работать именно с объектом UIDatabase, а не с Database, полученной из неё; это уже просто традиция - использовать NS.CurrentDatabase.

Я смотрел на currentview - начинал ещё более оголотело кидать квадратами.
Сейчас с накопленными знаниями посмотрю ещё разок.
Объекты этого класса рекордсмены по красным окнам. Я бы не смотрел в ту сторону..

P.S. Когда-то в агентах не срабатывал ws.ViewRefresh, поэтому делал сначало обновление бэкэндного объекта вьюхи (nv.Refresh), а затем уже ws.ViewRefresh.
 

Akupaka

А че я?.. О.о
04.10.2007
3 360
1
#16
Ничего страшного в нём нет, кроме того, что БД, полученная с UIDatabase ничего не возвратит в UnprocessedDocuments и т.п.
На моей практике, во многих случаях оно вообще не возвращает объект, или я не правильно его пользовал )
А запретное оно для программеров - так им и говорят: "низзя тебе юзать это свойство" ))
 

nvyush

Lotus team
22.04.2009
2 317
0
#17
Описал правильно и сие реализуемо.
Я смотрел на currentview - начинал ещё более оголотело кидать квадратами.
Сейчас с накопленными знаниями посмотрю ещё разок.
Через вьюшку даже лучше было бы...
Попробовал данный функционал в не так давно выложенной Omh базе http://codeby.net/ipb.html?s=&sh...st&p=171280
Без проблем получаю фоновым агентом текущее открытое представление/базу (выводится в строку состояния), но если начинаю активно действовать в рабочей области (открывать другие базы/представления) то очень быстро получаю "серый квадрат". Так что уточняю, кмк, сие нереализуемо без риска уронить клиента (практически 100%). Можно, конечно, ещё и с winapi поиграться, но пусть уж лучше пользователи сами обновляют.
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Допиленный код агента для любопытствующих</div></div><div class="sp-body"><div class="sp-content">
Код:
Sub Initialize
On Error Goto Errh
Dim ws As New NotesUIWorkspace
Dim uiview As NotesUIView
Dim uiDoc As NotesUiDocument
Dim Doc As NotesDocument
Set uiDoc = ws.CurrentDocument
Set Doc = uiDoc.Document
Dim i As Integer
Dim session As New NotesSession
Start:
Const MAX = 100
If Doc Is Nothing Then Exit Sub
If i >= MAX Then Exit Sub
If Doc.IsUIDocOpen Then 
Dim Data As String
Data = Doc.GetItemValue("Data")(0)
Dim Record As String
If i = MAX - 1 Then
Record = "Всё, глаза отвалились!"	
Else
Set uiview = ws.CurrentView
If uiview Is Nothing Then
Record = Cstr(Now) + ": uiview is nothing"
Else
Record = Cstr(Now) + " db.Name=" + uiview.View.Parent.Title + "; view.Name=" + uiview.View.Name
End If
End If
Print Cstr(i) + ". " + Record
i = i + 1
Sleep(0.5)
Goto Start
End If
Exit Sub
errh:
Msgbox Error & | in line | & Erl(), 64, |Lotus Notes (| & Lsi_info(2) & |)|
Exit Sub
End Sub
 

nvyush

Lotus team
22.04.2009
2 317
0
#18
Без проблем получаю фоновым агентом текущее открытое представление/базу...
Наткнулся на интересную фичу — если представление пустое (нет документов), ws.CurrentView возвращает Nothing. Таким образом, если уважаемый Omh фоновым агентом заполняет изначально пустое представление (папку?) возникает проблема определения, что оно(она) имеют фокус.