目前在作Quartz的部分
想讓別人包成Task或是傳functionName找出他的function
然後在傳到job內去Run
但目前第一次進入沒問題 第二次開始就會跳出
不可在已經完成的工作上呼叫start
每次執行完取消該任務可以嗎 另外該怎寫會比較好
public Task ReflectionFucntion(string ControllerName, string FunctionName)
{
return new Task(() =>
{
Type type = Type.GetType(QuartzConst.TASK_NAMESPACE + ControllerName);
//創建 {ControllerName} 類型的實例 {obj}
var obj = Activator.CreateInstance(type);
//取得 {FunctionName} 方法
MethodInfo method = type.GetMethod(FunctionName);
//調用 {FunctionName} 方法
method.Invoke(obj, new object[] { });
});
}
第一種 dataMap[QuartzConst.TASK_KEY] = new Task(() => { testFunction(); });
第二種 dataMap[QuartzConst.TASK_KEY] = ReflectionFucntion("Controller", "testFunction");
public class JobExecute : IJob
{
public async Task Execute(IJobExecutionContext context)
{
var dataMap = context.JobDetail.JobDataMap;
Task task = (Task)dataMap[QuartzConst.TASK_KEY];
await Task.Run(() =>
{
try
{
task.Start();
}
catch (Exception e)
{
// e = "不可在已經完成的工作上呼叫start"
}
});
}
}
在你的程式碼中,出現 "不可在已經完成的工作上呼叫start" 的問題是因為你試圖在已經完成的 Task
上調用 Start()
方法。一旦 Task
完成,它就無法再次啟動。此外,你也可以在每次任務執行完畢後取消該任務。
以下是修改後的程式碼,解決了這些問題:
public Task ReflectionFucntion(string ControllerName, string FunctionName)
{
return Task.Run(() =>
{
Type type = Type.GetType(QuartzConst.TASK_NAMESPACE + ControllerName);
//創建 {ControllerName} 類型的實例 {obj}
var obj = Activator.CreateInstance(type);
//取得 {FunctionName} 方法
MethodInfo method = type.GetMethod(FunctionName);
//調用 {FunctionName} 方法
method.Invoke(obj, new object[] { });
});
}
public class JobExecute : IJob
{
public async Task Execute(IJobExecutionContext context)
{
var dataMap = context.JobDetail.JobDataMap;
Task task = (Task)dataMap[QuartzConst.TASK_KEY];
if (task.Status != TaskStatus.Running && task.Status != TaskStatus.WaitingToRun)
{
await Task.Run(() =>
{
try
{
task = ReflectionFucntion("Controller", "testFunction");
task.Start();
}
catch (Exception e)
{
// 處理例外狀況
}
});
}
}
}
在修改後的程式碼中,我們使用 task.Status
屬性檢查 Task
的狀態,確保只有在 Task
還沒開始或正在運行時才執行該任務。如果 Task
已經完成,則會建立並啟動一個新的 Task
。同時,你也可以在每次任務執行完畢後取消該任務,可以使用 task.Dispose()
或其他適合的取消方法。
請注意,這只是一種解決方案,你可能需要根據你的需求進一步調整。
原因可能是因爲你的dataMap[QuartzConst.TASK_KEY]是全域變數
第二次呼叫沒有出現 “不可在已經完成的工作上呼叫start”
//Program.cs
static async Task Main(string[] args)
{
//呼叫Execute
TestNamespace A = new TestNamespace();
await A.Execute();
await A.Execute();
}
//方法的檔案
public class TestNamespace
{
//全域變數測試
private static Task _task ;
public async Task Execute()
{
Task task = ReflectionFucntion("ConsoleApp1.TestQuartz", "Test1");
try
{
await Task.Run(() =>
{
task.Start();
});
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
public static Task ReflectionFucntion(string ClassName, string FunctionName)
{
Task task = new Task(() =>
{
Type type = Type.GetType(ClassName);
//創建 {ClassName} 類型的實例 {obj}
var obj = Activator.CreateInstance(type);
//取得 {FunctionName} 方法
MethodInfo method = type.GetMethod(FunctionName);
//調用 {FunctionName} 方法
method.Invoke(obj, new object[] { });
});
return task;
}
}
調整使用全域變數 此時呼叫2次會出現 “不可在已經完成的工作上呼叫start”
//全域變數測試
private static Task _task = ReflectionFucntion("ConsoleApp1.TestQuartz", "Test1");
public async Task Execute()
{
Task task = _task;
try
{
await Task.Run(() =>
{
task.Start();
});
}
catch (Exception e)
{
Console.WriteLine(e);
}
}