Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 当两个任务中的任何一个任务完成时,需要在我的表单类中调用一个方法_.net_Async Await_Task - Fatal编程技术网

.net 当两个任务中的任何一个任务完成时,需要在我的表单类中调用一个方法

.net 当两个任务中的任何一个任务完成时,需要在我的表单类中调用一个方法,.net,async-await,task,.net,Async Await,Task,在一个表单中,在Load事件中,我需要启动两个任务(如下所示)。然后让它在其中一个完成时调用我的表单对象。我该怎么做 或者,我不明白这是对的吗?我确实将加载方法设置为异步。那么,这是否意味着它立即从Load调用返回,但没有像我使用wait调用LoadMetadata那样完成?因此表单的处理都是正确的,但是Load在其中一个任务完成之前不会执行所有代码 是这样吗?所以我很好。(我可能已经习惯了围绕线程进行的所有内务处理,我正在使其变得更加复杂。) private async void Loadin

在一个表单中,在Load事件中,我需要启动两个任务(如下所示)。然后让它在其中一个完成时调用我的表单对象。我该怎么做

或者,我不明白这是对的吗?我确实将加载方法设置为异步。那么,这是否意味着它立即从Load调用返回,但没有像我使用wait调用LoadMetadata那样完成?因此表单的处理都是正确的,但是Load在其中一个任务完成之前不会执行所有代码

是这样吗?所以我很好。(我可能已经习惯了围绕线程进行的所有内务处理,我正在使其变得更加复杂。)

private async void LoadingMetadata\u Load(对象发送方,事件参数e)
{ 
//加载元数据-这将创建一个任务并返回。
var result=await LoadMetadata(this、profile、source.Token);
}
专用静态异步任务LoadMetadata(LoadingMetadata dlg、DataSourceProfile配置文件、CancellationToken CancellationToken)
{
//我们创建一个十进制的TaskCompletionSource
var taskCompletionSource=新的taskCompletionSource();
//将lambda注册到cancellationToken中
cancellationToken.Register(()=>
{
//我们收到一条取消消息,取消TaskCompletionSource.Task
taskCompletionSource.TrySetCanceled();
});
//加载元数据
Task Task=Task.Run(()=>{profile.ReloadMetadata();返回true;});
//等待两个任务中的第一个任务完成
var completedTask=wait Task.WhenAny(Task,taskCompletionSource.Task);
//如果完成的任务是我们长期运行的操作,则设置其结果。
if(completedTask==任务)
{
//提取结果,任务完成,等待将立即返回
var结果=等待任务;
//设置taskCompletionSource结果
taskCompletionSource.TrySetResult(结果);
}
//关闭对话框
bool success=wait taskCompletionSource.Task;
dlg.DialogResult=success?DialogResult.OK:DialogResult.Cancel;
dlg.Close();
//返回TaskCompletionSource.Task的结果
回归成功;
}

为什么要在此处创建
TaskCompletionSource
?你这样做是为了“支持取消”吗?要允许取消您的工作,您只需将取消令牌传递给所有子任务,并在工作中检查其取消状态。此外,您对异步的理解似乎不正确:使用
async
注释您的方法,然后使用
wait
等待内部任务不会使您的代理立即返回。wait将强制您的代码在该点停止执行并释放线程,但在
wait
完成后,委托只会在继续部分完成一次。@julealgon我必须以这种方式取消,因为我正在调用的是第三方库。因此,我无法传递取消令牌。在“立即返回”节目中,我说错了话(这对我来说是全新的)。我想说的是,方法中的执行在该点等待,但执行会立即从该方法返回,从而允许调用它的代码继续。是这样吗?这对我来说仍然很奇怪,一个方法没有完成(当时),但仍然返回。这一切都很简单,但需要一点时间来适应。这与以前的正常情况相反。取消令牌什么时候取消?@PauloMorgado我有一个按钮点击处理程序。当他们在我显示的对话框中点击[Cancel]按钮时,所有这些都会被取消。我不确定异步代码在这里是否有帮助。如果且仅当对话框仍然打开时,您似乎希望对
profile.ReloadMetadata()
的结果执行某些操作。你为什么不那样做呢?
    private async void LoadingMetadata_Load(object sender, EventArgs e)
    { 
            // load the metadata - this creates a task and returns.
            var result = await LoadMetadata(this, profile, source.Token);
        }



    private static async Task<bool> LoadMetadata(LoadingMetadata dlg, DataSourceProfile profile, CancellationToken cancellationToken)
    {

        // We create a TaskCompletionSource of decimal
        var taskCompletionSource = new TaskCompletionSource<bool>();

        // Registering a lambda into the cancellationToken
        cancellationToken.Register(() =>
        {
            // We received a cancellation message, cancel the TaskCompletionSource.Task
            taskCompletionSource.TrySetCanceled();
        });

        // load the metadata
        Task<bool> task = Task.Run(() => { profile.ReloadMetadata(); return true; } );

        // Wait for the first task to finish among the two
        var completedTask = await Task.WhenAny(task, taskCompletionSource.Task);

        // If the completed task is our long running operation we set its result.
        if (completedTask == task)
        {
            // Extract the result, the task is finished and the await will return immediately
            var result = await task;

            // Set the taskCompletionSource result
            taskCompletionSource.TrySetResult(result);
        }

        // close the dialog
        bool success = await taskCompletionSource.Task;
        dlg.DialogResult = success ? DialogResult.OK : DialogResult.Cancel;
        dlg.Close();

        // Return the result of the TaskCompletionSource.Task
        return success;
    }