C# 如何在特定的运行任务上调用方法

C# 如何在特定的运行任务上调用方法,c#,methods,task,invoke,taskscheduler,C#,Methods,Task,Invoke,Taskscheduler,我是新来的 如何访问正确的任务并调用此任务的方法?任务有一个ID,我给它起了一个名字,我得到了一个TaskScheduler 我得到了一个异常,这是正确的: InvalidOperationException:调用线程无法访问此对象,因为该对象属于另一个线程 问题: 主要是使用CustomSplashScreenViewModel.StartSplashScreenAsync()启动一项任务。更多任务已启动并正在运行。当所有内容都加载后,我需要关闭SplashScreen 方法CustomSpl

我是新来的

如何访问正确的任务并调用此任务的方法?任务有一个ID,我给它起了一个名字,我得到了一个TaskScheduler

我得到了一个异常,这是正确的: InvalidOperationException:调用线程无法访问此对象,因为该对象属于另一个线程

问题: 主要是使用CustomSplashScreenViewModel.StartSplashScreenAsync()启动一项任务。更多任务已启动并正在运行。当所有内容都加载后,我需要关闭SplashScreen

方法CustomSplashScreenViewModel.CloseSplash(_splashTask,_taskSchedulerSplash);获取这些信息。调试时,_splashTask为“null”,在_taskSchedulerSplash中,它包含_splashTask。 在CloseSplash方法中,我喜欢调用_splash任务上的方法_view.Close()

我如何解决这个问题

public class Program
{
  private static readonly SingleThreadTaskScheduler _taskSchedulerSplash = new SingleThreadTaskScheduler(ApartmentState.STA);

  [ThreadStatic]
  private static Task _splashTask;

//        [STAThread]
  public static async Task Main()
  {       
    _splashTask = await Task.Factory.StartNew(() =>
    {
        return CustomSplashScreenViewModel.StartSplashScreenAsync();
    }, _taskSchedulerSplash);

    var taskScheduler = new SingleThreadTaskScheduler(ApartmentState.STA);
    var taskList = new List<Task>(); 

    var updateTask = Task.Run(InstallHelper.CheckForUpdatesAsync);
    updateTask.Wait();
    taskList.Add(updateTask);

    var tasks = await Task.Factory.ContinueWhenAll(taskList.ToArray(), result => Task.Factory.StartNew( ()=>AppStart(container), taskScheduler));
        tasks.Wait();
   }


   private static void App_MainWindowLoaded(object sender, EventArgs e)
   {
     CustomSplashScreenViewModel.CloseSplash(_splashTask, _taskSchedulerSplash);
   }
}

public class CustomSplashScreenViewModel
{
  private static Thread _currentThread;
  public static void CloseSplash(Task task, TaskScheduler taskScheduler)
  {
    if (_view!= null)
    {
      // Here i need the right Task and to invoke the following method
      // if I'm doing _view.Dispatcher.Invoke(new Action(_view.Close)); it doesn't 
      // work coz it's another STA Thread. Inside this class I can store the right task in 
      // a local variable. this works. But how to invoke it if the Task is already running?
      // I like to overgive the task - may it isn't possible. 
      _view.Close();      
    }
  }
}
公共类程序
{
私有静态只读SingleThreadTaskScheduler _taskSchedulerSplash=新的SingleThreadTaskScheduler(ApartmentState.STA);
[线程静态]
私有静态任务_-splashTask;
//[状态线程]
公共静态异步任务Main()
{       
_splashTask=wait Task.Factory.StartNew(()=>
{
返回CustomSplashScreenViewModel.StartSplashScreenAsync();
},_taskSchedulerSplash);
var taskScheduler=newsinglethreadtaskscheduler(ApartmentState.STA);
var taskList=新列表();
var updateTask=Task.Run(InstallHelper.CheckForUpdatesAsync);
updateTask.Wait();
taskList.Add(updateTask);
var tasks=wait Task.Factory.ContinueWhenAll(taskList.ToArray(),result=>Task.Factory.StartNew(()=>AppStart(container),taskScheduler));
任务。等待();
}
私有静态void App_MainWindowLoaded(对象发送方,事件参数e)
{
CustomSplashScreenViewModel.CloseSplash(\u splashTask,\u taskSchedulerSplash);
}
}
公共类自定义ScreenViewModel
{
私有静态线程_currentThread;
公共静态void CloseSplash(任务任务、任务调度器任务调度器)
{
如果(_view!=null)
{
//在这里,我需要正确的任务并调用以下方法
//如果我正在执行_view.Dispatcher.Invoke(newaction(_view.Close)),它不会
//工作,因为它是另一个STA线程。在这个类中,我可以存储正确的任务
//一个局部变量。这是有效的。但是如果任务已经在运行,如何调用它呢?
//我喜欢过度地完成这项任务——也许这是不可能的。
_view.Close();
}
}
}

非常感谢您的帮助。

您不能更改正在运行的任务。但是,您可以调度将在同一个调度器上运行的另一个任务,该任务应该可以满足您的需要(它将在拥有启动屏幕的同一个STA线程上运行):

另一方面,为了使代码更容易理解,我建议使用以下方法:

  • 为自定义任务计划程序引入
    TaskFactory
    实例,而不是将
    TaskScheduler
    task.Factory
    一起使用
  • 避免
    任务。工厂。在所有
    任务时继续。等待
    ;使用
    Task.whalll
    wait
  • public static void CloseSplash(Task task, TaskScheduler taskScheduler)
    {
      if (_view!= null)
      {
        Task.Factory.StartNew(() => _view.Close(), taskScheduler);
      }
    }