1 2
Как такое написать на VB.NET? в избранное  новое горячее всё    подписка   модер. 
От: senglory 
Дата: 08.02.10 07:09
C# Set method timeout using Generics


I'm out of ideas...
Re: Как такое написать на VB.NET? в избранное  новое    модер. 
От: _FRED_ экспертProfile on Google
Дата: 08.02.10 07:44
Оценка: +2
Здравствуйте, senglory, Вы писали:

S>C# Set method timeout using Generics

S>I'm out of ideas...

Ужас какой — не стоит пользоваться тем примером ни из васика, ни из шарпа. Лучше сначала расскажите, что пытаетесь сделать. Написать обобщённый метод вызова с таймаутом всего чего угодно (как по ссылке) идея не самая удачная и хорошо не делается.

Если же требуется вызывать с таймаутом некоторый набор методов, то сами эти методы должны подобные вызовы поддерживать. Если интересно, как это сделать, то следует описать более конкретную задачу детальнее.
What I've learned about software engineering: 1) Listen to smart people 2) Prefer simple to clever 3) Have no ego 4) Shut the fuck up.
Не бойтесь делиться своими методами работы. Большинству людей будет тупо лень их использовать.
Re[2]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: cadet354my twitter
Дата: 08.02.10 12:50
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, senglory, Вы писали:


S>>C# Set method timeout using Generics

S>>I'm out of ideas...

_FR>Ужас какой — не стоит пользоваться тем примером ни из васика, ни из шарпа. Лучше сначала расскажите, что пытаетесь сделать. Написать обобщённый метод вызова с таймаутом всего чего угодно (как по ссылке) идея не самая удачная и хорошо не делается.


_FR>Если же требуется вызывать с таймаутом некоторый набор методов, то сами эти методы должны подобные вызовы поддерживать. Если интересно, как это сделать, то следует описать более конкретную задачу детальнее.

тут не вызвать методы, а прекратить ждать , автору в коментариях справедливо написали:
/*
Nice idea, but I think creating a new thread is a bit heavyweight, especially if the wrapped function needs to be called many times a second. Why not use the standard .Net async pattern? Something like this (untested):
*/
public static T Limex(Func F, int Timeout, out bool Completed)
{
var iar = F.BeginInvoke(null, new object());
if (iar.AsyncWaitHandle.WaitOne(Timeout))
{
Completed = true;
return F.EndInvoke(iar);
}

Completed = false;
return default(T);
}
... << RSDN@Home 1.2.0 alpha 4 rev. 1270>>
Re[3]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: senglory 
Дата: 08.02.10 15:18
Здравствуйте, cadet354, Вы писали:

C>Здравствуйте, _FRED_, Вы писали:


_FR>>Здравствуйте, senglory, Вы писали:


S>>>C# Set method timeout using Generics

S>>>I'm out of ideas...

_FR>>Ужас какой — не стоит пользоваться тем примером ни из васика, ни из шарпа. Лучше сначала расскажите, что пытаетесь сделать. Написать обобщённый метод вызова с таймаутом всего чего угодно (как по ссылке) идея не самая удачная и хорошо не делается.


_FR>>Если же требуется вызывать с таймаутом некоторый набор методов, то сами эти методы должны подобные вызовы поддерживать. Если интересно, как это сделать, то следует описать более конкретную задачу детальнее.

C>тут не вызвать методы, а прекратить ждать , автору в коментариях справедливо написали:
C>
C>/*
C>Nice idea, but I think creating a new thread is a bit heavyweight, especially if the wrapped function needs to be called many times a second. Why not use the standard .Net async pattern? Something like this (untested):
C>*/
C>public static T Limex(Func F, int Timeout, out bool Completed)
C>{
C>var iar = F.BeginInvoke(null, new object());
C>if (iar.AsyncWaitHandle.WaitOne(Timeout))
C>{
C>Completed = true;
C>return F.EndInvoke(iar);
C>}

C>Completed = false;
C>return default(T);
C>} 


C>


Хорошо, как такое изобразить на VB.NET? Мне надо какую-то функцию вызвать и дать ей секунд 5 на выполнение. Не уложилась — TimeOutException или что-то типа этого.
Re[3]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: _FRED_ экспертProfile on Google
Дата: 08.02.10 15:45
Здравствуйте, cadet354, Вы писали:

_FR>>Если же требуется вызывать с таймаутом некоторый набор методов, то сами эти методы должны подобные вызовы поддерживать. Если интересно, как это сделать, то следует описать более конкретную задачу детальнее.

C>тут не вызвать методы, а прекратить ждать , автору в коментариях справедливо написали:

Если надо прекратить ждать и вас не касается, как завершится метод, то "общим" образом реализовать можно. Но предложенное решение не вызывает EndInvoke если ожидание оказалось неуспешным. ИМХО, это "не чисто". EndInvoke должен быть вызван в любом случае. Как этого добиться — отдельный этюд.
What I've learned about software engineering: 1) Listen to smart people 2) Prefer simple to clever 3) Have no ego 4) Shut the fuck up.
Не бойтесь делиться своими методами работы. Большинству людей будет тупо лень их использовать.
Re[4]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: senglory 
Дата: 08.02.10 17:22
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, cadet354, Вы писали:


_FR>>>Если же требуется вызывать с таймаутом некоторый набор методов, то сами эти методы должны подобные вызовы поддерживать. Если интересно, как это сделать, то следует описать более конкретную задачу детальнее.

C>>тут не вызвать методы, а прекратить ждать , автору в коментариях справедливо написали:

_FR>Если надо прекратить ждать и вас не касается, как завершится метод, то "общим" образом реализовать можно. Но предложенное решение не вызывает EndInvoke если ожидание оказалось неуспешным. ИМХО, это "не чисто". EndInvoke должен быть вызван в любом случае. Как этого добиться — отдельный этюд.


А как, действительно?
Re[5]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: romangr 
Дата: 09.02.10 10:38
Здравствуйте, senglory, Вы писали:

S>Здравствуйте, _FRED_, Вы писали:


_FR>>Если надо прекратить ждать и вас не касается, как завершится метод, то "общим" образом реализовать можно. Но предложенное решение не вызывает EndInvoke если ожидание оказалось неуспешным. ИМХО, это "не чисто". EndInvoke должен быть вызван в любом случае. Как этого добиться — отдельный этюд.


S>А как, действительно?


Например, как-то так:
public static T RunAsync3<T>(Func<T> func, int timeout, out bool completed)
{
    IAsyncResult ar = null;
    var hasResult = false;
    var cookie = new object();
    lock (cookie)
    {
        ar = func.BeginInvoke((_) =>
        {
            lock (cookie)
            {
                if (!hasResult)
                {
                    func.EndInvoke(ar);
                }
            }
        }, null);
        if (ar.AsyncWaitHandle.WaitOne(timeout))
        {
            completed = true;
            hasResult = true;
            return func.EndInvoke(ar);
        }
    }
    completed = false;
    return default(T);
}
... << RSDN@Home 1.2.0 alpha 4 rev. 1238>>
Re[6]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: cadet354my twitter
Дата: 09.02.10 11:10
Здравствуйте, romangr, Вы писали:

R>Здравствуйте, senglory, Вы писали:


S>>Здравствуйте, _FRED_, Вы писали:



R>Например, как-то так:

R>
R>public static T RunAsync3<T>(Func<T> func, int timeout, out bool completed)
R>{
R>    IAsyncResult ar = null;
R>    var hasResult = false;
R>    var cookie = new object();
R>    lock (cookie)
R>    {
R>        ar = func.BeginInvoke((_) =>
R>        {
R>            lock (cookie)
R>            {
R>                if (!hasResult)
R>                {
R>                    func.EndInvoke(ar);
R>                }
R>            }
R>        }, null);
R>        if (ar.AsyncWaitHandle.WaitOne(timeout))
R>        {
R>            completed = true;
R>            hasResult = true;
R>            return func.EndInvoke(ar);
R>        }
R>    }
R>    completed = false;
R>    return default(T);
R>}
R>

lock зачем?
... << RSDN@Home 1.2.0 alpha 4 rev. 1270>>
Re[7]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: Codechanger 
Дата: 09.02.10 11:28
Здравствуйте, cadet354, Вы писали:

C>Здравствуйте, romangr, Вы писали:


R>>Здравствуйте, senglory, Вы писали:


S>>>Здравствуйте, _FRED_, Вы писали:



R>>Например, как-то так:

R>>
R>>public static T RunAsync3<T>(Func<T> func, int timeout, out bool completed)
R>>{
R>>    IAsyncResult ar = null;
R>>    var hasResult = false;
R>>    var cookie = new object();
R>>    lock (cookie)
R>>    {
R>>        ar = func.BeginInvoke((_) =>
R>>        {
R>>            lock (cookie)
R>>            {
R>>                if (!hasResult)
R>>                {
R>>                    func.EndInvoke(ar);
R>>                }
R>>            }
R>>        }, null);
R>>        if (ar.AsyncWaitHandle.WaitOne(timeout))
R>>        {
R>>            completed = true;
R>>            hasResult = true;
R>>            return func.EndInvoke(ar);
R>>        }
R>>    }
R>>    completed = false;
R>>    return default(T);
R>>}
R>>

C>lock зачем?

Лок в приведенном коде будет работать странно...
Re[8]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: romangr 
Дата: 09.02.10 12:44
Здравствуйте, Codechanger, Вы писали:

C>Лок в приведенном коде будет работать странно...


Попытаюсь объяснить.

public static T RunAsync<T>(Func<T> func, int timeout, out bool completed)
{
    IAsyncResult ar = null;
    var hasResult = false;
    var cookie = new object();
    lock (cookie) //1
    {
        ar = func.BeginInvoke((_) => //2
        {
            lock (cookie) //3
            {
                if (!hasResult)
                {
                    func.EndInvoke(ar); //4
                }
            }
        }, null);
        if (ar.AsyncWaitHandle.WaitOne(timeout))
        {
            completed = true;
            hasResult = true;
            return func.EndInvoke(ar); //5
        }
    }
    completed = false; //6
    return default(T);
}


В наши задачи входит следующее.
1. Обязательно выполнить func.EndInvoke в любом случае — уложились ли мы в отведенное время, либо нет
2. Если мы вызываем func.EndInvoke — мы должны сделать это один раз.

При вызове в строке (2) присваивание ar = func.BeginInvoke может пройти позже, чем использование ar в строке (4),
т.к. коллбэк выполняется в отдельном потоке, а пути планировщика неисповедимы, поэтому нужны локи (1) и (3)

Если функция выполнилась нормально, то основной поток дойдет до точки (5)
и благодаря локам (1) и (3) func.EndInvoke выполнится один раз в точке (5)

Если же функция превысит таймаут, то мы провалимся в точку (6) и освободим лок (1),
а func.EndInvoke выполнится в точке (4), когда наша функция завершится
... << RSDN@Home 1.2.0 alpha 4 rev. 1238>>
Re[6]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: senglory 
Дата: 09.02.10 16:19
Здравствуйте, romangr, Вы писали:

R>Здравствуйте, senglory, Вы писали:


S>>Здравствуйте, _FRED_, Вы писали:


_FR>>>Если надо прекратить ждать и вас не касается, как завершится метод, то "общим" образом реализовать можно. Но предложенное решение не вызывает EndInvoke если ожидание оказалось неуспешным. ИМХО, это "не чисто". EndInvoke должен быть вызван в любом случае. Как этого добиться — отдельный этюд.


S>>А как, действительно?


R>Например, как-то так:

R>
R>public static T RunAsync3<T>(Func<T> func, int timeout, out bool completed)
R>{
R>    IAsyncResult ar = null;
R>    var hasResult = false;
R>    var cookie = new object();
R>    lock (cookie)
R>    {
R>        ar = func.BeginInvoke((_) =>
R>        {
R>            lock (cookie)
R>            {
R>                if (!hasResult)
R>                {
R>                    func.EndInvoke(ar);
R>                }
R>            }
R>        }, null);
R>        if (ar.AsyncWaitHandle.WaitOne(timeout))
R>        {
R>            completed = true;
R>            hasResult = true;
R>            return func.EndInvoke(ar);
R>        }
R>    }
R>    completed = false;
R>    return default(T);
R>}
R>



Замечательно, а на VB.NET как это все написать?
Re[7]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: romangr 
Дата: 09.02.10 17:44
Здравствуйте, senglory, Вы писали:

S>Замечательно, а на VB.NET как это все написать?


Для начала перепишем код на C#
public static T RunAsync<T>(Func<T> func, int timeout, out bool completed)
{
    var hasResult = false;
    var cookie = new object();
    var result = default(T);
    var ar = func.BeginInvoke((tmp) =>
    {
        lock (cookie)
        {
            if (!hasResult)
            {
                hasResult = true;
                result = func.EndInvoke(tmp);
            }
        }
    }, null);
    if (ar.AsyncWaitHandle.WaitOne(timeout))
    {
        completed = true;
        lock (cookie)
        {
            if (hasResult)
            {
                return result;
            }
            hasResult = true;
            return func.EndInvoke(ar);
        }
    }
    completed = false;
    return default(T);
}


Для VB придется поработать ручками:
Public Class Class1
    Private Class State(Of T)
        Public Sub Callback(ByVal ar As IAsyncResult)
            SyncLock Me.cookie
                If Not Me.hasResult Then
                    Me.hasResult = True
                    Me.result = Me.func.EndInvoke(ar)
                End If
            End SyncLock
        End Sub

        Public cookie As Object
        Public func As Func(Of T)
        Public hasResult As Boolean
        Public result As T
    End Class

    Public Shared Function RunAsync(Of T)(ByVal func As Func(Of T), ByVal timeout As Integer, ByRef completed As Boolean) As T
        Dim state As New State(Of T)
        state.cookie = New Object
        state.func = func
        Dim ar As IAsyncResult = func.BeginInvoke(New AsyncCallback(AddressOf state.Callback), Nothing)
        If ar.AsyncWaitHandle.WaitOne(timeout) Then
            completed = True
            SyncLock state.cookie
                If state.hasResult Then
                    Return state.result
                End If
                state.hasResult = True
                Return func.EndInvoke(ar)
            End SyncLock
        End If
        completed = False
        Return CType(Nothing, T)
    End Function
End Class
... << RSDN@Home 1.2.0 alpha 4 rev. 1238>>
Re[7]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: crackoff 
Дата: 09.02.10 17:48
Здравствуйте, senglory, Вы писали:

S>Замечательно, а на VB.NET как это все написать?


Давай я сделаю это за тебя. Копируем вышеприведенный код, компилим, берем рефлектор и дизассемблим в VB.


Public Shared Function RunAsync(Of T)(ByVal func As Func(Of T), ByVal timeout As Integer, <Out> ByRef completed As Boolean) As T
    Dim callback As AsyncCallback = Nothing
    Dim ar As IAsyncResult = Nothing
    Dim hasResult As Boolean = False
    Dim cookie As New Object
    SyncLock cookie
        If (callback Is Nothing) Then
            callback = Function (ByVal _ As IAsyncResult) 
                SyncLock MyBase.cookie
                    If Not MyBase.hasResult Then
                        MyBase.func.EndInvoke(MyBase.ar)
                    End If
                End SyncLock
            End Function
        End If
        ar = func.BeginInvoke(callback, Nothing)
        If ar.AsyncWaitHandle.WaitOne(timeout) Then
            completed = True
            hasResult = True
            Return func.EndInvoke(ar)
        End If
    End SyncLock
    completed = False
    Return CType(Nothing, T)
End Function


К сожалению, VB 2008 у меня нет, поэтому скомпилить и проверить не могу.
Re[8]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: romangr 
Дата: 09.02.10 18:03
Оценка:2 (1)
Здравствуйте, crackoff, Вы писали:

C>Давай я сделаю это за тебя. Копируем вышеприведенный код, компилим, берем рефлектор и дизассемблим в VB.

хъ
C>К сожалению, VB 2008 у меня нет, поэтому скомпилить и проверить не могу.

Я проверял, рефлектор облажался
... << RSDN@Home 1.2.0 alpha 4 rev. 1238>>
Re[9]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: romangr 
Дата: 09.02.10 18:16
Здравствуйте, romangr, Вы писали:

От локов можно избавиться, применив CAS:
    public static T RunAsync<T>(Func<T> func, int timeout, out bool completed)
    {
        int state = 0;
        var result = default(T);
        var ar = func.BeginInvoke((tmp) =>
        {
            if (Interlocked.CompareExchange(ref state, 1, 0) == 0)
            {
                result = func.EndInvoke(tmp);
                Thread.VolatileWrite(ref state, 2);
            }
        }, null);
        if (ar.AsyncWaitHandle.WaitOne(timeout))
        {
            completed = true;
            if (Interlocked.CompareExchange(ref state, 2, 0) == 0)
            {
                return func.EndInvoke(ar);
            }
            while (Thread.VolatileRead(ref state) != 2)
            {
            }
            return result;
        }
        completed = false;
        return default(T);
    }
... << RSDN@Home 1.2.0 alpha 4 rev. 1238>>
Re[8]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: senglory 
Дата: 10.02.10 15:04
Здравствуйте, romangr, Вы писали:

R>Здравствуйте, senglory, Вы писали:


S>>Замечательно, а на VB.NET как это все написать?


R>Для начала перепишем код на C#

R>
R>public static T RunAsync<T>(Func<T> func, int timeout, out bool completed)
R>{
R>    var hasResult = false;
R>    var cookie = new object();
R>    var result = default(T);
R>    var ar = func.BeginInvoke((tmp) =>
R>    {
R>        lock (cookie)
R>        {
R>            if (!hasResult)
R>            {
R>                hasResult = true;
R>                result = func.EndInvoke(tmp);
R>            }
R>        }
R>    }, null);
R>    if (ar.AsyncWaitHandle.WaitOne(timeout))
R>    {
R>        completed = true;
R>        lock (cookie)
R>        {
R>            if (hasResult)
R>            {
R>                return result;
R>            }
R>            hasResult = true;
R>            return func.EndInvoke(ar);
R>        }
R>    }
R>    completed = false;
R>    return default(T);
R>}
R>


R>Для VB придется поработать ручками:

R>
R>Public Class Class1
R>    Private Class State(Of T)
R>        Public Sub Callback(ByVal ar As IAsyncResult)
R>            SyncLock Me.cookie
R>                If Not Me.hasResult Then
R>                    Me.hasResult = True
R>                    Me.result = Me.func.EndInvoke(ar)
R>                End If
R>            End SyncLock
R>        End Sub

R>        Public cookie As Object
R>        Public func As Func(Of T)
R>        Public hasResult As Boolean
R>        Public result As T
R>    End Class

R>    Public Shared Function RunAsync(Of T)(ByVal func As Func(Of T), ByVal timeout As Integer, ByRef completed As Boolean) As T
R>        Dim state As New State(Of T)
R>        state.cookie = New Object
R>        state.func = func
R>        Dim ar As IAsyncResult = func.BeginInvoke(New AsyncCallback(AddressOf state.Callback), Nothing)
R>        If ar.AsyncWaitHandle.WaitOne(timeout) Then
R>            completed = True
R>            SyncLock state.cookie
R>                If state.hasResult Then
R>                    Return state.result
R>                End If
R>                state.hasResult = True
R>                Return func.EndInvoke(ar)
R>            End SyncLock
R>        End If
R>        completed = False
R>        Return CType(Nothing, T)
R>    End Function
R>End Class

R>



Хорошо, допустим что у меня есть:


Public Shared Function VerifyDB(ByVal dbFilePath As String, ByRef result As DBTESTSRESULTS) As Boolean
...
End Function


Как будет выглядеть вызов моей функции из этого кода?
Re[9]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: romangr 
Дата: 11.02.10 07:04
Оценка:8 (1)
Здравствуйте, senglory, Вы писали:

S>Хорошо, допустим что у меня есть:



S>
S>Public Shared Function VerifyDB(ByVal dbFilePath As String, ByRef result As DBTESTSRESULTS) As Boolean
S>...
S>End Function
S>


S>Как будет выглядеть вызов моей функции из этого кода?


Учу пользоваться лямбдами. Дорого.

Public Shared Sub CallVerifyDB()
    Dim result As DBTESTSRESULTS
    Dim completed As Boolean
    Dim funcResult As Boolean

    funcResult = RunAsync(Function() VerifyDB("path", result), 1000, completed)
    If (completed) Then
        Console.WriteLine("Function completed")
    Else
        Console.WriteLine("Timeout expired")
    End If
End Sub
... << RSDN@Home 1.2.0 alpha 4 rev. 1238>>
Re[9]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: cadet354my twitter
Дата: 11.02.10 10:14
Здравствуйте, romangr, Вы писали:



R>В наши задачи входит следующее.

R>1. Обязательно выполнить func.EndInvoke в любом случае — уложились ли мы в отведенное время, либо нет
R>2. Если мы вызываем func.EndInvoke — мы должны сделать это один раз.

R>При вызове в строке (2) присваивание ar = func.BeginInvoke может пройти позже, чем использование ar в строке (4),

R>т.к. коллбэк выполняется в отдельном потоке, а пути планировщика неисповедимы, поэтому нужны локи (1) и (3)

R>Если функция выполнилась нормально, то основной поток дойдет до точки (5)

R>и благодаря локам (1) и (3) func.EndInvoke выполнится один раз в точке (5)

R>Если же функция превысит таймаут, то мы провалимся в точку (6) и освободим лок (1),

R>а func.EndInvoke выполнится в точке (4), когда наша функция завершится
а просто передавать это (выполнились нормально или нет) со state не проще?
... << RSDN@Home 1.2.0 alpha 4 rev. 1270>>
Re[10]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: romangr 
Дата: 11.02.10 11:36
Здравствуйте, cadet354, Вы писали:

C>а просто передавать это (выполнились нормально или нет) со state не проще?


Когда я это на VB переводил, слегка модифицировал, вроде понятнее получилось здесь
Автор: romangr
Дата: 09.02.10

А вообще мне постановка задачи не нравится, я ее тут порешал just for fun, ну и в VB потренировался.
Узнал, что в лямбдах в VB только Expressions могут быть, в отличие от C#
... << RSDN@Home 1.2.0 alpha 4 rev. 1238>>
Re[11]: Как такое написать на VB.NET? в избранное  новое    модер. 
От: senglory 
Дата: 03.03.10 14:54
Хорошо, в вот такое как на VB.NET изобразить?


db.GetTable<GeoName>().Insert(() => new GeoName
                    {
                        GeonameId = nID,
                        Name = sName,
                        AsciiName = sNameAsc,
                        Countrycode = sCntry,
                        Alternatenames = sAlt
                    });
1 2