我想讓我的腦袋圍繞使用Action委託類型用於在第三方COM DLL中調用方法掛起時強制超時。經過大量搜索後,我發現我可以使用Action <>或Func <>並根據所調用的方法是否返回參數傳遞最多4個通用參數。使用參數調用泛型函數的實現超時
對於這個實例,我想調用一個返回void和2個參數的一系列方法的超時。接下來是我放在一起的代碼,但我無法確定如何正確編碼BeginInvoke,我被提示放置「T arg1」和「T arg2」,但是當我輸入param1或param2時VS2008告訴我這些值是不確定的。
下面是代碼,因爲它是迄今:
static void CallAndWait(Action<T, T> action, int timeout)
{
Thread subThread = null;
Action<T, T> wrappedAction = (param1, param2) =>
{
subThread = Thread.CurrentThread;
action(param1, param2);
};
IAsyncResult result = wrappedAction.BeginInvoke(param1, param2, null, null);
if (((timeout != -1) && !result.IsCompleted) &&
(!result.AsyncWaitHandle.WaitOne(timeout, false) || !result.IsCompleted))
{
if (subThread != null)
{
subThread.Abort();
}
//TODO: close external resource.
throw new TimeoutException();
}
else
{
action.EndInvoke(result);
}
}
任何想法,對什麼是錯在這裏將不勝感激。
下面是基於對輸入
由於第一評論迄今重新編輯的代碼。以下編譯。在調用它的時候,我似乎無法得到正確的語法。
public static void CallAndWait<T1, T2>(Action<T1, T2> action, int timeout)
{
Thread subThread = null;
T1 param1 = default(T1);
T2 param2 = default(T2);
Action<T1, T2> wrappedAction = (p1, p2) =>
{
subThread = Thread.CurrentThread;
action(param1, param2);
};
IAsyncResult result = wrappedAction.BeginInvoke(param1, param2, null, null);
if (((timeout != -1) && !result.IsCompleted) &&
(!result.AsyncWaitHandle.WaitOne(timeout, false) || !result.IsCompleted))
{
if (subThread != null)
{
subThread.Abort();
}
//TODO: close external resource.
throw new TimeoutException();
}
else
{
action.EndInvoke(result);
}
}
我試圖通過調用下面的方法用它來測試這一點:
public void LongTimeProcess(int a, string b)
{
Thread.Sleep(a);
}
但下面的代碼是不正確的:
Action<int, string> action = (s1, s2) => LongTimeProcess(s1, s2);
CallAndWait<int, string>(action(1500, "hello"), 500);
更新代碼 我已發佈代碼供將來由論壇用戶參考。下面的代碼似乎工作。 唯一需要檢查的是當我們的「action.EndInvoke(result)」結果與動作沒有關聯時,我的單元測試會導致在第二次調用例程的同一個函數時引發異常。這可能是因爲我的LongProcess只是一個Thread.sleep,在這種情況下,這意味着我的第二次調用沒有中止。
public static void CallAndWait<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2, int timeout)
{
Thread subThread = null;
Action<T1, T2> wrappedAction = (p1, p2) =>
{
subThread = Thread.CurrentThread;
action(arg1, arg2);
};
IAsyncResult result = wrappedAction.BeginInvoke(arg1, arg2, null, null);
if (((timeout != -1) && !result.IsCompleted) &&
(!result.AsyncWaitHandle.WaitOne(timeout, false) || !result.IsCompleted))
{
if (subThread != null)
{
subThread.Abort();
}
//TODO: close external resource.
throw new TimeoutException();
}
else
{
action.EndInvoke(result);
}
}
我發現你的錯誤,並更新了我的答案。 –
看到它:http://stackoverflow.com/questions/4238345/asynchronously-wait-for-taskt-to-complete-with-timeout – 2012-08-13 12:58:35